* stream_output.h : stream output module
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: stream_output.h,v 1.8 2003/02/25 17:17:43 fenrir Exp $
+ * $Id: stream_output.h,v 1.9 2003/03/11 19:02:30 fenrir Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Laurent Aimar <fenrir@via.ecp.fr>
vlc_fourcc_t i_fourcc;
void *p_format; // WAVEFORMATEX or BITMAPINFOHEADER
-
};
struct sout_fifo_t
sout_buffer_t **pp_last;
};
+/* for mux */
struct sout_input_t
{
- vlc_mutex_t lock;
+// vlc_mutex_t lock;
sout_instance_t *p_sout;
sout_packet_format_t input_format;
sout_fifo_t *p_fifo;
- void *p_mux_data;
+ void *p_sys;
+};
+
+/* for packetizr */
+struct sout_packetizer_input_t
+{
+
+ sout_instance_t *p_sout;
+ sout_packet_format_t input_format;
+
+// vlc_mutex_t lock;
+ int i_nb_inputs;
+ sout_input_t **pp_inputs;
+
+ int i_nb_mux; // not really used, just usefull with TAB_*
+ sout_mux_t **pp_mux;
+
};
#define SOUT_METHOD_NONE 0x00
#define SOUT_METHOD_FILE 0x10
#define SOUT_METHOD_NETWORK 0x20
-
struct sout_access_out_t
{
VLC_COMMON_MEMBERS
#define SOUT_MUX_CAP_ERR_UNKNOWN 0x01
#define SOUT_MUX_CAP_ERR_UNIMPLEMENTED 0x02
-typedef struct sout_instance_sys_t sout_instance_sys_t;
-struct sout_instance_t
+typedef struct sout_mux_sys_t sout_mux_sys_t;
+struct sout_mux_t
{
VLC_COMMON_MEMBERS
+ module_t *p_module;
+ sout_instance_t *p_sout;
- char * psz_dest;
- char * psz_access;
- char * psz_mux;
- char * psz_name;
-
- int i_method;
+ char *psz_mux;
sout_access_out_t *p_access;
- module_t *p_mux;
- void *p_mux_data;
- int i_mux_preheader;
- int (* pf_mux_capacity) ( sout_instance_t *,
- int, void *, void *);
- int (* pf_mux_addstream )( sout_instance_t *,
- sout_input_t * );
- int (* pf_mux_delstream )( sout_instance_t *,
- sout_input_t * );
- int (* pf_mux ) ( sout_instance_t * );
+ int i_preheader;
+ int (* pf_capacity) ( sout_mux_t *,
+ int, void *, void *);
+ int (* pf_addstream )( sout_mux_t *,
+ sout_input_t * );
+ int (* pf_delstream )( sout_mux_t *,
+ sout_input_t * );
+ int (* pf_mux ) ( sout_mux_t * );
- vlc_mutex_t lock;
-
+ /* here are all inputs accepted by muxer */
int i_nb_inputs;
sout_input_t **pp_inputs;
+
+ /* mux private */
+ sout_mux_sys_t *p_sys;
+
+// /* creater private */
+// void *p_sys_owner;
+
+ /* XXX private to stream_output.c */
+ /* if muxer doesn't support adding stream at any time then we first wait
+ * for stream then we refuse all stream and start muxing */
+ vlc_bool_t b_add_stream_any_time;
+ vlc_bool_t b_waiting_stream;
+ /* we wait one second after first stream added */
+ mtime_t i_add_stream_start;
+};
+
+typedef struct sout_instance_sys_t sout_instance_sys_t;
+struct sout_instance_t
+{
+ VLC_COMMON_MEMBERS
+
+ /* complete sout string like udp/ts:239.255.12.42#file/ps://essai.ps */
+ char * psz_sout;
+
+ /* here are stored the parsed psz_sout */
+ int i_nb_dest;
+ char **ppsz_dest;
+
+ /* muxer data */
+ int i_preheader; /* max over all muxer */
+
+ int i_nb_mux;
+ sout_mux_t **pp_mux;
+
+ /* here are all packetizer inputs accepted by at least one muxer */
+ vlc_mutex_t lock;
+ int i_nb_inputs;
+ sout_packetizer_input_t **pp_inputs;
+
+ /* sout private */
sout_instance_sys_t *p_sys;
};
#define sout_InputNew( a, b ) __sout_InputNew( VLC_OBJECT(a), b )
-VLC_EXPORT( sout_input_t *, __sout_InputNew, ( vlc_object_t *, sout_packet_format_t * ) );
-VLC_EXPORT( int, sout_InputDelete, ( sout_input_t * ) );
-VLC_EXPORT( int, sout_InputSendBuffer, ( sout_input_t *, sout_buffer_t* ) );
+VLC_EXPORT( sout_packetizer_input_t *, __sout_InputNew, ( vlc_object_t *, sout_packet_format_t * ) );
+VLC_EXPORT( int, sout_InputDelete, ( sout_packetizer_input_t * ) );
+VLC_EXPORT( int, sout_InputSendBuffer, ( sout_packetizer_input_t *, sout_buffer_t* ) );
VLC_EXPORT( sout_buffer_t*, sout_BufferNew, ( sout_instance_t *, size_t ) );
VLC_EXPORT( int, sout_BufferRealloc,( sout_instance_t *, sout_buffer_t*, size_t ) );
* Collection of useful common types and macros definitions
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vlc_common.h,v 1.57 2003/03/04 21:12:04 gbazin Exp $
+ * $Id: vlc_common.h,v 1.58 2003/03/11 19:02:30 fenrir Exp $
*
* Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr>
typedef struct sout_instance_t sout_instance_t;
typedef struct sout_fifo_t sout_fifo_t;
typedef struct sout_input_t sout_input_t;
+typedef struct sout_packetizer_input_t sout_packetizer_input_t;
typedef struct sout_buffer_t sout_buffer_t;
typedef struct sout_packet_format_t sout_packet_format_t;
typedef struct sout_access_out_t sout_access_out_t;
+typedef struct sout_mux_t sout_mux_t;
typedef struct sout_access_out_sys_t sout_access_out_sys_t;
/* Decoders */
* udp.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: udp.c,v 1.5 2003/03/03 14:21:08 gbazin Exp $
+ * $Id: udp.c,v 1.6 2003/03/11 19:02:30 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
return( VLC_EGENERIC );
}
+
if( p_access->psz_access != NULL &&
!strcmp( p_access->psz_access, "rtp" ) )
{
- if( p_access->p_sout->psz_mux != NULL &&
- *p_access->p_sout->psz_mux &&
- strcmp( p_access->p_sout->psz_mux, "ts" ) &&
- strcmp( p_access->p_sout->psz_mux, "ts_dvbpsi" ) )
- {
- msg_Err( p_access, "rtp ouput work only with ts payload" );
- free( p_sys );
- return( VLC_EGENERIC );
- }
+ msg_Warn( p_access, "becarefull that rtp ouput work only with ts payload(not an error)" );
p_sys->b_rtpts = 1;
}
else
return( VLC_EGENERIC );
}
+ srand( (uint32_t)mdate());
p_sys->p_buffer = NULL;
- p_sys->i_sequence_number = 12; // FIXME should be random, used by rtp
- p_sys->i_ssrc = 4212; // FIXME " " " " " "
+ p_sys->i_sequence_number = rand()&0xffff;
+ p_sys->i_ssrc = rand()&0xffffffff;
p_access->pf_write = Write;
p_access->pf_seek = Seek;
/* add rtp/ts header */
p_sys->p_buffer->p_buffer[0] = 0x80;
p_sys->p_buffer->p_buffer[1] = 0x21; // mpeg2-ts
+
p_sys->p_buffer->p_buffer[2] =
( p_sys->i_sequence_number >> 8 )&0xff;
p_sys->p_buffer->p_buffer[3] =
p_sys->i_sequence_number&0xff;
+ p_sys->i_sequence_number++;
p_sys->p_buffer->p_buffer[4] = ( i_timestamp >> 24 )&0xff;
p_sys->p_buffer->p_buffer[5] = ( i_timestamp >> 16 )&0xff;
* avi.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: avi.c,v 1.9 2003/03/03 14:21:08 gbazin Exp $
+ * $Id: avi.c,v 1.10 2003/03/11 19:02:30 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
-static int Capability(sout_instance_t *, int , void *, void * );
-static int AddStream( sout_instance_t *, sout_input_t * );
-static int DelStream( sout_instance_t *, sout_input_t * );
-static int Mux ( sout_instance_t * );
+static int Capability(sout_mux_t *, int , void *, void * );
+static int AddStream( sout_mux_t *, sout_input_t * );
+static int DelStream( sout_mux_t *, sout_input_t * );
+static int Mux ( sout_mux_t * );
-static sout_buffer_t *avi_HeaderCreateRIFF( sout_instance_t *p_sout );
-static sout_buffer_t *avi_HeaderCreateidx1( sout_instance_t *p_sout );
+static sout_buffer_t *avi_HeaderCreateRIFF( sout_mux_t * );
+static sout_buffer_t *avi_HeaderCreateidx1( sout_mux_t * );
static void SetFCC( uint8_t *p, char *fcc )
{
avi_idx1_entry_t *entry;
} avi_idx1_t;
-typedef struct sout_mux_s
+struct sout_mux_sys_t
{
int i_streams;
int i_stream_video;
avi_idx1_t idx1;
off_t i_idx1_size;
-} sout_mux_t;
+};
/*****************************************************************************
* Open:
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
- sout_instance_t *p_sout = (sout_instance_t*)p_this;
- sout_mux_t *p_mux;
- sout_buffer_t *p_hdr;
+ sout_mux_t *p_mux = (sout_mux_t*)p_this;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
+ sout_buffer_t *p_hdr;
- p_mux = malloc( sizeof( sout_mux_t ) );
- p_mux->i_streams = 0;
- p_mux->i_stream_video = -1;
- p_mux->i_movi_size = 0;
+ p_sys = malloc( sizeof( sout_mux_sys_t ) );
+ p_sys->i_streams = 0;
+ p_sys->i_stream_video = -1;
+ p_sys->i_movi_size = 0;
- p_mux->idx1.i_entry_count = 0;
- p_mux->idx1.i_entry_max = 10000;
- p_mux->idx1.entry = calloc( p_mux->idx1.i_entry_max, sizeof( avi_idx1_entry_t ) );
+ p_sys->idx1.i_entry_count = 0;
+ p_sys->idx1.i_entry_max = 10000;
+ p_sys->idx1.entry = calloc( p_sys->idx1.i_entry_max, sizeof( avi_idx1_entry_t ) );
- msg_Info( p_sout, "Open" );
+ msg_Info( p_mux, "Open" );
- p_sout->pf_mux_capacity = Capability;
- p_sout->pf_mux_addstream = AddStream;
- p_sout->pf_mux_delstream = DelStream;
- p_sout->pf_mux = Mux;
- p_sout->p_mux_data = (void*)p_mux;
- p_sout->i_mux_preheader = 8; // (fourcc,length) header
+ p_mux->pf_capacity = Capability;
+ p_mux->pf_addstream = AddStream;
+ p_mux->pf_delstream = DelStream;
+ p_mux->pf_mux = Mux;
+ p_mux->p_sys = p_sys;
+ p_mux->i_preheader = 8; // (fourcc,length) header
/* room to add header at the end */
- p_hdr = sout_BufferNew( p_sout, HDR_SIZE );
+ p_hdr = sout_BufferNew( p_mux->p_sout, HDR_SIZE );
memset( p_hdr->p_buffer, 0, HDR_SIZE );
- sout_AccessOutWrite( p_sout->p_access, p_hdr );
+ sout_AccessOutWrite( p_mux->p_access, p_hdr );
return VLC_SUCCESS;
}
static void Close( vlc_object_t * p_this )
{
- sout_instance_t *p_sout = (sout_instance_t*)p_this;
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
+ sout_mux_t *p_mux = (sout_mux_t*)p_this;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
+
sout_buffer_t *p_hdr, *p_idx1;
int i_stream;
- msg_Info( p_sout, "Close" );
+ msg_Info( p_mux, "Close" );
/* first create idx1 chunk (write at the end of the stream */
- p_idx1 = avi_HeaderCreateidx1( p_sout );
- p_mux->i_idx1_size = p_idx1->i_size;
- sout_AccessOutWrite( p_sout->p_access, p_idx1 );
+ p_idx1 = avi_HeaderCreateidx1( p_mux );
+ p_sys->i_idx1_size = p_idx1->i_size;
+ sout_AccessOutWrite( p_mux->p_access, p_idx1 );
/* calculate some value for headers creations */
- for( i_stream = 0; i_stream < p_mux->i_streams; i_stream++ )
+ for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
{
avi_stream_t *p_stream;
- p_stream = &p_mux->stream[i_stream];
+ p_stream = &p_sys->stream[i_stream];
p_stream->f_fps = 25;
if( p_stream->i_duration > 0 )
(uint64_t)p_stream->i_totalsize /
(uint64_t)p_stream->i_duration;
}
- msg_Err( p_sout,"stream[%d] duration:%lld totalsize:%lld frames:%d fps:%f kb/s:%d",
- i_stream,
- p_stream->i_duration/1000000, p_stream->i_totalsize,
- p_stream->i_frames,
- p_stream->f_fps, p_stream->i_bitrate/1024 );
+ msg_Err( p_mux, "stream[%d] duration:%lld totalsize:%lld frames:%d fps:%f kb/s:%d",
+ i_stream,
+ p_stream->i_duration/1000000, p_stream->i_totalsize,
+ p_stream->i_frames,
+ p_stream->f_fps, p_stream->i_bitrate/1024 );
}
- p_hdr = avi_HeaderCreateRIFF( p_sout );
- sout_AccessOutSeek( p_sout->p_access, 0 );
- sout_AccessOutWrite( p_sout->p_access, p_hdr );
+ p_hdr = avi_HeaderCreateRIFF( p_mux );
+ sout_AccessOutSeek( p_mux->p_access, 0 );
+ sout_AccessOutWrite( p_mux->p_access, p_hdr );
}
-static int Capability( sout_instance_t *p_sout, int i_query, void *p_args, void *p_answer )
+static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, void *p_answer )
{
switch( i_query )
{
}
}
-static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
+static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
- avi_stream_t *p_stream;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
+ avi_stream_t *p_stream;
- if( p_mux->i_streams >= 100 )
+ if( p_sys->i_streams >= 100 )
{
- msg_Err( p_sout, "too many streams" );
+ msg_Err( p_mux, "too many streams" );
return( -1 );
}
if( p_input->input_format.p_format == NULL )
{
- msg_Err( p_sout, "stream descriptor missing" );
+ msg_Err( p_mux, "stream descriptor missing" );
return( -1 );
}
- msg_Dbg( p_sout, "adding input" );
- p_input->p_mux_data = malloc( sizeof( int ) );
+ msg_Dbg( p_mux, "adding input" );
+ p_input->p_sys = malloc( sizeof( int ) );
- *((int*)p_input->p_mux_data) = p_mux->i_streams;
- p_stream = &p_mux->stream[p_mux->i_streams];
+ *((int*)p_input->p_sys) = p_sys->i_streams;
+ p_stream = &p_sys->stream[p_sys->i_streams];
switch( p_input->input_format.i_cat )
{
(WAVEFORMATEX*)p_input->input_format.p_format;
p_stream->i_cat = AUDIO_ES;
- p_stream->fcc[0] = '0' + p_mux->i_streams / 10;
- p_stream->fcc[1] = '0' + p_mux->i_streams % 10;
+ p_stream->fcc[0] = '0' + p_sys->i_streams / 10;
+ p_stream->fcc[1] = '0' + p_sys->i_streams % 10;
p_stream->fcc[2] = 'w';
p_stream->fcc[3] = 'b';
(BITMAPINFOHEADER*)p_input->input_format.p_format;;
p_stream->i_cat = VIDEO_ES;
- p_stream->fcc[0] = '0' + p_mux->i_streams / 10;
- p_stream->fcc[1] = '0' + p_mux->i_streams % 10;
+ p_stream->fcc[0] = '0' + p_sys->i_streams / 10;
+ p_stream->fcc[1] = '0' + p_sys->i_streams % 10;
p_stream->fcc[2] = 'd';
p_stream->fcc[3] = 'c';
- if( p_mux->i_stream_video < 0 )
+ if( p_sys->i_stream_video < 0 )
{
- p_mux->i_stream_video = p_mux->i_streams;
+ p_sys->i_stream_video = p_sys->i_streams;
}
p_stream->p_wf = NULL;
p_stream->p_bih = malloc( p_bih->biSize );
p_stream->i_frames = 0;
p_stream->i_duration = 0;
- p_mux->i_streams++;
+ p_sys->i_streams++;
return( 0 );
}
-static int DelStream( sout_instance_t *p_sout, sout_input_t *p_input )
+static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
{
-// sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
- msg_Dbg( p_sout, "removing input" );
+ msg_Dbg( p_mux, "removing input" );
- free( p_input->p_mux_data ); p_input->p_mux_data = NULL;
+ free( p_input->p_sys ); p_input->p_sys = NULL;
return( 0 );
}
-static int Mux ( sout_instance_t *p_sout )
+static int Mux ( sout_mux_t *p_mux )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
- avi_stream_t *p_stream;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
+ avi_stream_t *p_stream;
int i_stream;
int i;
- for( i = 0; i < p_sout->i_nb_inputs; i++ )
+ for( i = 0; i < p_mux->i_nb_inputs; i++ )
{
int i_count;
sout_fifo_t *p_fifo;
- i_stream = *((int*)p_sout->pp_inputs[i]->p_mux_data );
- p_stream = &p_mux->stream[i_stream];
+ i_stream = *((int*)p_mux->pp_inputs[i]->p_sys );
+ p_stream = &p_sys->stream[i_stream];
- p_fifo = p_sout->pp_inputs[i]->p_fifo;
+ p_fifo = p_mux->pp_inputs[i]->p_fifo;
i_count = p_fifo->i_depth;
while( i_count > 0 )
{
p_stream->i_totalsize += p_data->i_size;
/* add idx1 entry for this frame */
- p_idx = &p_mux->idx1.entry[p_mux->idx1.i_entry_count];
+ p_idx = &p_sys->idx1.entry[p_sys->idx1.i_entry_count];
memcpy( p_idx->fcc, p_stream->fcc, 4 );
p_idx->i_flags = AVIIF_KEYFRAME;
- p_idx->i_pos = p_mux->i_movi_size + 4;
+ p_idx->i_pos = p_sys->i_movi_size + 4;
p_idx->i_length= p_data->i_size;
- p_mux->idx1.i_entry_count++;
- if( p_mux->idx1.i_entry_count >= p_mux->idx1.i_entry_max )
+ p_sys->idx1.i_entry_count++;
+ if( p_sys->idx1.i_entry_count >= p_sys->idx1.i_entry_max )
{
- p_mux->idx1.i_entry_max += 10000;
- p_mux->idx1.entry = realloc( p_mux->idx1.entry,
- p_mux->idx1.i_entry_max * sizeof( avi_idx1_entry_t ) );
+ p_sys->idx1.i_entry_max += 10000;
+ p_sys->idx1.entry = realloc( p_sys->idx1.entry,
+ p_sys->idx1.i_entry_max * sizeof( avi_idx1_entry_t ) );
}
- if( sout_BufferReallocFromPreHeader( p_sout, p_data, 8 ) )
+ if( sout_BufferReallocFromPreHeader( p_mux->p_sout, p_data, 8 ) )
{
/* there isn't enough data in preheader */
sout_buffer_t *p_hdr;
- p_hdr = sout_BufferNew( p_sout, 8 );
+ p_hdr = sout_BufferNew( p_mux->p_sout, 8 );
SetFCC( p_hdr->p_buffer, p_stream->fcc );
SetDWLE( p_hdr->p_buffer + 4, p_data->i_size );
- sout_AccessOutWrite( p_sout->p_access, p_hdr );
- p_mux->i_movi_size += p_hdr->i_size;
+ sout_AccessOutWrite( p_mux->p_access, p_hdr );
+ p_sys->i_movi_size += p_hdr->i_size;
}
else
if( p_data->i_size & 0x01 )
{
- sout_BufferRealloc( p_sout, p_data, p_data->i_size + 1 );
+ sout_BufferRealloc( p_mux->p_sout, p_data, p_data->i_size + 1 );
p_data->i_size += 1;
}
- sout_AccessOutWrite( p_sout->p_access, p_data );
- p_mux->i_movi_size += p_data->i_size;
+ sout_AccessOutWrite( p_mux->p_access, p_data );
+ p_sys->i_movi_size += p_data->i_size;
i_count--;
}
bo_AddDWordLE( &_bo_sav_, p_bo->i_buffer - _bo_sav_.i_buffer - 4 ); \
return( i_err );
-static int avi_HeaderAdd_avih( sout_instance_t *p_sout,
+static int avi_HeaderAdd_avih( sout_mux_t *p_mux,
buffer_out_t *p_bo )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
- avi_stream_t *p_video = NULL;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
+ avi_stream_t *p_video = NULL;
int i_stream;
uint32_t i_microsecperframe;
int i_maxbytespersec;
int i_totalframes;
AVI_BOX_ENTER( "avih" );
- if( p_mux->i_stream_video >= 0 )
+ if( p_sys->i_stream_video >= 0 )
{
- p_video = &p_mux->stream[p_mux->i_stream_video];
+ p_video = &p_sys->stream[p_sys->i_stream_video];
if( p_video->i_frames <= 0 )
{
p_video = NULL;
{
i_microsecperframe =
(uint32_t)( (float)1000000 /
- (float)p_mux->stream[p_mux->i_stream_video].f_fps );
- i_totalframes = p_mux->stream[p_mux->i_stream_video].i_frames;
+ (float)p_sys->stream[p_sys->i_stream_video].f_fps );
+ i_totalframes = p_sys->stream[p_sys->i_stream_video].i_frames;
}
else
{
- msg_Warn( p_sout, "avi file without audio video track isn't a good idea..." );
+ msg_Warn( p_mux, "avi file without audio video track isn't a good idea..." );
i_microsecperframe = 0;
i_totalframes = 0;
}
- for( i_stream = 0,i_maxbytespersec = 0; i_stream < p_mux->i_streams; i_stream++ )
+ for( i_stream = 0,i_maxbytespersec = 0; i_stream < p_sys->i_streams; i_stream++ )
{
- if( p_mux->stream[p_mux->i_stream_video].i_duration > 0 )
+ if( p_sys->stream[p_sys->i_stream_video].i_duration > 0 )
{
i_maxbytespersec +=
- p_mux->stream[p_mux->i_stream_video].i_totalsize /
- p_mux->stream[p_mux->i_stream_video].i_duration;
+ p_sys->stream[p_sys->i_stream_video].i_totalsize /
+ p_sys->stream[p_sys->i_stream_video].i_duration;
}
}
AVIF_ISINTERLEAVED ); /* flags */
bo_AddDWordLE( p_bo, i_totalframes );
bo_AddDWordLE( p_bo, 0 ); /* initial frame */
- bo_AddDWordLE( p_bo, p_mux->i_streams ); /* streams count */
+ bo_AddDWordLE( p_bo, p_sys->i_streams ); /* streams count */
bo_AddDWordLE( p_bo, 1024 * 1024 ); /* suggested buffer size */
if( p_video )
{
AVI_BOX_EXIT( 0 );
}
-static int avi_HeaderAdd_strh( sout_instance_t *p_sout,
+static int avi_HeaderAdd_strh( sout_mux_t *p_mux,
buffer_out_t *p_bo,
avi_stream_t *p_stream )
{
-// sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
AVI_BOX_ENTER( "strh" );
switch( p_stream->i_cat )
AVI_BOX_EXIT( 0 );
}
-static int avi_HeaderAdd_strf( sout_instance_t *p_sout,
+static int avi_HeaderAdd_strf( sout_mux_t *p_mux,
buffer_out_t *p_bo,
avi_stream_t *p_stream )
{
-// sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
AVI_BOX_ENTER( "strf" );
switch( p_stream->i_cat )
AVI_BOX_EXIT( 0 );
}
-static int avi_HeaderAdd_strl( sout_instance_t *p_sout,
+static int avi_HeaderAdd_strl( sout_mux_t *p_mux,
buffer_out_t *p_bo,
avi_stream_t *p_stream )
{
-// sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
AVI_BOX_ENTER_LIST( "strl" );
- avi_HeaderAdd_strh( p_sout, p_bo, p_stream );
- avi_HeaderAdd_strf( p_sout, p_bo, p_stream );
+ avi_HeaderAdd_strh( p_mux, p_bo, p_stream );
+ avi_HeaderAdd_strf( p_mux, p_bo, p_stream );
AVI_BOX_EXIT( 0 );
}
-static sout_buffer_t *avi_HeaderCreateRIFF( sout_instance_t *p_sout )
+static sout_buffer_t *avi_HeaderCreateRIFF( sout_mux_t *p_mux )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
sout_buffer_t *p_hdr;
int i_stream;
int i_maxbytespersec;
int i_junk;
buffer_out_t bo;
- p_hdr = sout_BufferNew( p_sout, HDR_SIZE );
+ p_hdr = sout_BufferNew( p_mux->p_sout, HDR_SIZE );
memset( p_hdr->p_buffer, 0, HDR_SIZE );
bo_Init( &bo, HDR_SIZE, p_hdr->p_buffer );
bo_AddFCC( &bo, "RIFF" );
- bo_AddDWordLE( &bo, p_mux->i_movi_size + HDR_SIZE - 8 + p_mux->i_idx1_size );
+ bo_AddDWordLE( &bo, p_sys->i_movi_size + HDR_SIZE - 8 + p_sys->i_idx1_size );
bo_AddFCC( &bo, "AVI " );
bo_AddFCC( &bo, "LIST" );
bo_AddDWordLE( &bo, HDR_SIZE - 8);
bo_AddFCC( &bo, "hdrl" );
- avi_HeaderAdd_avih( p_sout, &bo );
- for( i_stream = 0,i_maxbytespersec = 0; i_stream < p_mux->i_streams; i_stream++ )
+ avi_HeaderAdd_avih( p_mux, &bo );
+ for( i_stream = 0,i_maxbytespersec = 0; i_stream < p_sys->i_streams; i_stream++ )
{
- avi_HeaderAdd_strl( p_sout, &bo, &p_mux->stream[i_stream] );
+ avi_HeaderAdd_strl( p_mux, &bo, &p_sys->stream[i_stream] );
}
i_junk = HDR_SIZE - bo.i_buffer - 8 - 12;
bo.i_buffer += i_junk;
bo_AddFCC( &bo, "LIST" );
- bo_AddDWordLE( &bo, p_mux->i_movi_size + 4 );
+ bo_AddDWordLE( &bo, p_sys->i_movi_size + 4 );
bo_AddFCC( &bo, "movi" );
return( p_hdr );
}
-static sout_buffer_t * avi_HeaderCreateidx1( sout_instance_t *p_sout )
+static sout_buffer_t * avi_HeaderCreateidx1( sout_mux_t *p_mux )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
sout_buffer_t *p_idx1;
uint32_t i_idx1_size;
unsigned int i;
buffer_out_t bo;
- i_idx1_size = 16 * p_mux->idx1.i_entry_count;
+ i_idx1_size = 16 * p_sys->idx1.i_entry_count;
- p_idx1 = sout_BufferNew( p_sout, i_idx1_size + 8 );
+ p_idx1 = sout_BufferNew( p_mux->p_sout, i_idx1_size + 8 );
memset( p_idx1->p_buffer, 0, i_idx1_size );
bo_Init( &bo, i_idx1_size, p_idx1->p_buffer );
bo_AddFCC( &bo, "idx1" );
bo_AddDWordLE( &bo, i_idx1_size );
- for( i = 0; i < p_mux->idx1.i_entry_count; i++ )
+ for( i = 0; i < p_sys->idx1.i_entry_count; i++ )
{
- bo_AddFCC( &bo, p_mux->idx1.entry[i].fcc );
- bo_AddDWordLE( &bo, p_mux->idx1.entry[i].i_flags );
- bo_AddDWordLE( &bo, p_mux->idx1.entry[i].i_pos );
- bo_AddDWordLE( &bo, p_mux->idx1.entry[i].i_length );
+ bo_AddFCC( &bo, p_sys->idx1.entry[i].fcc );
+ bo_AddDWordLE( &bo, p_sys->idx1.entry[i].i_flags );
+ bo_AddDWordLE( &bo, p_sys->idx1.entry[i].i_pos );
+ bo_AddDWordLE( &bo, p_sys->idx1.entry[i].i_length );
}
return( p_idx1 );
* dummy.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: dummy.c,v 1.6 2003/03/03 14:21:08 gbazin Exp $
+ * $Id: dummy.c,v 1.7 2003/03/11 19:02:30 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
-static int Capability(sout_instance_t *, int, void *, void * );
-static int AddStream( sout_instance_t *, sout_input_t * );
-static int DelStream( sout_instance_t *, sout_input_t * );
-static int Mux ( sout_instance_t * );
+static int Capability(sout_mux_t *, int, void *, void * );
+static int AddStream( sout_mux_t *, sout_input_t * );
+static int DelStream( sout_mux_t *, sout_input_t * );
+static int Mux ( sout_mux_t * );
/*****************************************************************************
* Module descriptor
set_description( _("Dummy muxer") );
set_capability( "sout mux", 5 );
add_shortcut( "dummy" );
+ add_shortcut( "es" );
set_callbacks( Open, Close );
vlc_module_end();
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
- sout_instance_t *p_sout = (sout_instance_t*)p_this;
+ sout_mux_t *p_mux = (sout_mux_t*)p_this;
- msg_Info( p_sout, "Open" );
+ msg_Info( p_mux, "Open" );
- p_sout->pf_mux_capacity = Capability;
- p_sout->pf_mux_addstream = AddStream;
- p_sout->pf_mux_delstream = DelStream;
- p_sout->pf_mux = Mux;
+ p_mux->pf_capacity = Capability;
+ p_mux->pf_addstream = AddStream;
+ p_mux->pf_delstream = DelStream;
+ p_mux->pf_mux = Mux;
return VLC_SUCCESS;
}
static void Close( vlc_object_t * p_this )
{
- sout_instance_t *p_sout = (sout_instance_t*)p_this;
- msg_Info( p_sout, "Close" );
+ sout_mux_t *p_mux = (sout_mux_t*)p_this;
+
+ msg_Info( p_mux, "Close" );
}
-static int Capability( sout_instance_t *p_sout, int i_query, void *p_args, void *p_answer )
+static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, void *p_answer )
{
switch( i_query )
{
}
}
-static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
+static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
{
- msg_Dbg( p_sout, "adding input" );
+ msg_Dbg( p_mux, "adding input" );
return( 0 );
}
-static int DelStream( sout_instance_t *p_sout, sout_input_t *p_input )
+static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
{
- msg_Dbg( p_sout, "removing input" );
+ msg_Dbg( p_mux, "removing input" );
return( 0 );
}
-static int Mux ( sout_instance_t *p_sout )
+static int Mux ( sout_mux_t *p_mux )
{
int i;
- for( i = 0; i < p_sout->i_nb_inputs; i++ )
+ for( i = 0; i < p_mux->i_nb_inputs; i++ )
{
int i_count;
sout_fifo_t *p_fifo;
- p_fifo = p_sout->pp_inputs[i]->p_fifo;
+ p_fifo = p_mux->pp_inputs[i]->p_fifo;
i_count = p_fifo->i_depth;
while( i_count > 0 )
{
p_data = sout_FifoGet( p_fifo );
- sout_AccessOutWrite( p_sout->p_access, p_data );
+ sout_AccessOutWrite( p_mux->p_access, p_data );
i_count--;
}
* ps.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: ps.c,v 1.10 2003/03/03 14:21:08 gbazin Exp $
+ * $Id: ps.c,v 1.11 2003/03/11 19:02:30 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
-static int Capability(sout_instance_t *, int, void *, void * );
-static int AddStream( sout_instance_t *, sout_input_t * );
-static int DelStream( sout_instance_t *, sout_input_t * );
-static int Mux ( sout_instance_t * );
+static int Capability(sout_mux_t *, int, void *, void * );
+static int AddStream( sout_mux_t *, sout_input_t * );
+static int DelStream( sout_mux_t *, sout_input_t * );
+static int Mux ( sout_mux_t * );
static void SetWBE ( uint8_t *p, uint16_t v )
{
} ps_stream_t;
-typedef struct sout_mux_s
+struct sout_mux_sys_t
{
int i_stream_id_mpga;
int i_pes_count;
int i_system_header;
-} sout_mux_t;
+};
/*****************************************************************************
* Open:
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
- sout_instance_t *p_sout = (sout_instance_t*)p_this;
- sout_mux_t *p_mux;
+ sout_mux_t *p_mux = (sout_mux_t*)p_this;
+ sout_mux_sys_t *p_sys;
- msg_Info( p_sout, "Open" );
+ msg_Info( p_mux, "Open" );
- p_mux = malloc( sizeof( sout_mux_t ) );
+ p_sys = malloc( sizeof( sout_mux_sys_t ) );
- p_sout->pf_mux_capacity = Capability;
- p_sout->pf_mux_addstream = AddStream;
- p_sout->pf_mux_delstream = DelStream;
- p_sout->pf_mux = Mux;
- p_sout->p_mux_data = (void*)p_mux;
- p_sout->i_mux_preheader = 30; // really enough for a pes header
+ p_mux->pf_capacity = Capability;
+ p_mux->pf_addstream = AddStream;
+ p_mux->pf_delstream = DelStream;
+ p_mux->pf_mux = Mux;
+ p_mux->p_sys = p_sys;
+ p_mux->i_preheader = 30; // really enough for a pes header
- p_mux->i_stream_id_mpga = 0xc0;
- p_mux->i_stream_id_a52 = 0x80;
- p_mux->i_stream_id_mpgv = 0xe0;
- p_mux->i_audio_bound = 0;
- p_mux->i_video_bound = 0;
- p_mux->i_system_header = 0;
- p_mux->i_pes_count = 0;
+ p_sys->i_stream_id_mpga = 0xc0;
+ p_sys->i_stream_id_a52 = 0x80;
+ p_sys->i_stream_id_mpgv = 0xe0;
+ p_sys->i_audio_bound = 0;
+ p_sys->i_video_bound = 0;
+ p_sys->i_system_header = 0;
+ p_sys->i_pes_count = 0;
return VLC_SUCCESS;
}
static void Close( vlc_object_t * p_this )
{
- sout_instance_t *p_sout = (sout_instance_t*)p_this;
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
+ sout_mux_t *p_mux = (sout_mux_t*)p_this;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
+
sout_buffer_t *p_end;
- msg_Info( p_sout, "Close" );
+ msg_Info( p_mux, "Close" );
- p_end = sout_BufferNew( p_sout, 4 );
+ p_end = sout_BufferNew( p_mux->p_sout, 4 );
SetDWBE( p_end->p_buffer, 0x01b9 );
- sout_AccessOutWrite( p_sout->p_access, p_end );
-
- free( p_mux );
+ sout_AccessOutWrite( p_mux->p_access, p_end );
- p_sout->p_mux_data = NULL;
+ free( p_sys );
}
-static int Capability( sout_instance_t *p_sout, int i_query, void *p_args, void *p_answer )
+static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, void *p_answer )
{
switch( i_query )
{
}
}
-static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
+static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
ps_stream_t *p_stream;
- msg_Dbg( p_sout, "adding input" );
- p_input->p_mux_data = (void*)p_stream = malloc( sizeof( ps_stream_t ) );
+ msg_Dbg( p_mux, "adding input" );
+ p_input->p_sys = (void*)p_stream = malloc( sizeof( ps_stream_t ) );
p_stream->i_ok = 0;
switch( p_input->input_format.i_cat )
{
switch( p_input->input_format.i_fourcc )
{
case VLC_FOURCC( 'm', 'p', 'g', 'v' ):
- p_stream->i_stream_id = p_mux->i_stream_id_mpgv;
- p_mux->i_stream_id_mpgv++;
- p_mux->i_video_bound++;
+ p_stream->i_stream_id = p_sys->i_stream_id_mpgv;
+ p_sys->i_stream_id_mpgv++;
+ p_sys->i_video_bound++;
break;
default:
return( -1 );
{
case VLC_FOURCC( 'a', '5', '2', ' ' ):
case VLC_FOURCC( 'a', '5', '2', 'b' ):
- p_stream->i_stream_id = p_mux->i_stream_id_a52 | ( 0xbd << 8 );
- p_mux->i_stream_id_a52++;
- p_mux->i_audio_bound++;
+ p_stream->i_stream_id = p_sys->i_stream_id_a52 | ( 0xbd << 8 );
+ p_sys->i_stream_id_a52++;
+ p_sys->i_audio_bound++;
break;
case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
- p_stream->i_stream_id = p_mux->i_stream_id_mpga;
- p_mux->i_stream_id_mpga++;
- p_mux->i_audio_bound++;
+ p_stream->i_stream_id = p_sys->i_stream_id_mpga;
+ p_sys->i_stream_id_mpga++;
+ p_sys->i_audio_bound++;
break;
default:
return( -1 );
}
p_stream->i_ok = 1;
- msg_Dbg( p_sout, "adding input stream_id:0x%x [OK]", p_stream->i_stream_id );
+ msg_Dbg( p_mux, "adding input stream_id:0x%x [OK]", p_stream->i_stream_id );
return( 0 );
}
-static int DelStream( sout_instance_t *p_sout, sout_input_t *p_input )
+static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
{
- ps_stream_t *p_stream =(ps_stream_t*)p_input->p_mux_data;
+ ps_stream_t *p_stream =(ps_stream_t*)p_input->p_sys;
- msg_Dbg( p_sout, "removing input" );
+ msg_Dbg( p_mux, "removing input" );
if( p_stream )
{
free( p_stream );
}
- return( 0 );
+ return( VLC_SUCCESS );
}
-static int MuxWritePackHeader( sout_instance_t *p_sout,
+static int MuxWritePackHeader( sout_mux_t *p_mux,
mtime_t i_dts )
{
sout_buffer_t *p_hdr;
i_src = i_dts * 9 / 100;
- p_hdr = sout_BufferNew( p_sout, 18 );
+ p_hdr = sout_BufferNew( p_mux->p_sout, 18 );
bits_initwrite( &bits, 14, p_hdr->p_buffer );
bits_write( &bits, 32, 0x01ba );
bits_write( &bits, 2, 0x01 ); // FIXME ??
bits_write( &bits, 5, 0x1f ); // FIXME reserved
bits_write( &bits, 3, 0 ); // stuffing bytes
p_hdr->i_size = 14;
- sout_AccessOutWrite( p_sout->p_access, p_hdr );
+ sout_AccessOutWrite( p_mux->p_access, p_hdr );
return( 0 );
}
-static int MuxWriteSystemHeader( sout_instance_t *p_sout )
+static int MuxWriteSystemHeader( sout_mux_t *p_mux )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
sout_buffer_t *p_hdr;
bits_buffer_t bits;
- p_hdr = sout_BufferNew( p_sout, 12 );
+ p_hdr = sout_BufferNew( p_mux->p_sout, 12 );
bits_initwrite( &bits, 12, p_hdr->p_buffer );
bits_write( &bits, 32, 0x01bb );
bits_write( &bits, 22, 0 ); // FIXME rate bound
bits_write( &bits, 1, 1 );
- bits_write( &bits, 6, p_mux->i_audio_bound );
+ bits_write( &bits, 6, p_sys->i_audio_bound );
bits_write( &bits, 1, 0 ); // fixed flag
bits_write( &bits, 1, 0 ); // CSPS flag
bits_write( &bits, 1, 0 ); // system audio lock flag
bits_write( &bits, 1, 1 ); // marker bit
- bits_write( &bits, 5, p_mux->i_video_bound );
+ bits_write( &bits, 5, p_sys->i_video_bound );
bits_write( &bits, 1, 0 ); // packet rate restriction flag
bits_write( &bits, 7, 0x7f ); // reserved bits
/* FIXME missing stream_id ... */
- sout_AccessOutWrite( p_sout->p_access, p_hdr );
+ sout_AccessOutWrite( p_mux->p_access, p_hdr );
return( 0 );
}
/* return stream number to be muxed */
-static int MuxGetStream( sout_instance_t *p_sout,
+static int MuxGetStream( sout_mux_t *p_mux,
int *pi_stream,
mtime_t *pi_dts )
{
int i_stream;
int i;
- for( i = 0, i_dts = 0, i_stream = -1; i < p_sout->i_nb_inputs; i++ )
+ for( i = 0, i_dts = 0, i_stream = -1; i < p_mux->i_nb_inputs; i++ )
{
sout_fifo_t *p_fifo;
- p_fifo = p_sout->pp_inputs[i]->p_fifo;
+ p_fifo = p_mux->pp_inputs[i]->p_fifo;
if( p_fifo->i_depth > 1 )
{
}
-static int Mux ( sout_instance_t *p_sout )
+static int Mux ( sout_mux_t *p_mux )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
- mtime_t i_dts;
- int i_stream;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
+ mtime_t i_dts;
+ int i_stream;
for( ;; )
{
sout_fifo_t *p_fifo;
sout_buffer_t *p_data;
- if( MuxGetStream( p_sout, &i_stream, &i_dts ) < 0 )
+ if( MuxGetStream( p_mux, &i_stream, &i_dts ) < 0 )
{
- return( 0 );
+ return( VLC_SUCCESS );
}
- p_input = p_sout->pp_inputs[i_stream];
+ p_input = p_mux->pp_inputs[i_stream];
p_fifo = p_input->p_fifo;
- p_stream = (ps_stream_t*)p_input->p_mux_data;
+ p_stream = (ps_stream_t*)p_input->p_sys;
- if( p_mux->i_pes_count % 30 == 0)
+ if( p_sys->i_pes_count % 30 == 0)
{
- MuxWritePackHeader( p_sout, i_dts );
+ MuxWritePackHeader( p_mux, i_dts );
}
- if( p_mux->i_pes_count % 300 == 0 )
+ if( p_sys->i_pes_count % 300 == 0 )
{
// MuxWriteSystemHeader( p_sout );
}
p_data = sout_FifoGet( p_fifo );
- E_( EStoPES )( p_sout, &p_data, p_data, p_stream->i_stream_id, 1);
- sout_AccessOutWrite( p_sout->p_access, p_data );
+ E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1);
+ sout_AccessOutWrite( p_mux->p_access, p_data );
- p_mux->i_pes_count++;
+ p_sys->i_pes_count++;
}
return( 0 );
* ts.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: ts.c,v 1.14 2003/03/03 14:21:08 gbazin Exp $
+ * $Id: ts.c,v 1.15 2003/03/11 19:02:30 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
uint8_t *p_decoder_specific_info;
} ts_stream_t;
-typedef struct sout_mux_s
+struct sout_mux_sys_t
{
int i_pcr_pid;
int i_stream_id_mpga;
int i_mpeg4_streams;
-} sout_mux_t;
+};
/*****************************************************************************
static void Close ( vlc_object_t * );
-static int Capability(sout_instance_t *, int, void *, void * );
-static int AddStream( sout_instance_t *, sout_input_t * );
-static int DelStream( sout_instance_t *, sout_input_t * );
-static int Mux ( sout_instance_t * );
+static int Capability(sout_mux_t *, int, void *, void * );
+static int AddStream( sout_mux_t *, sout_input_t * );
+static int DelStream( sout_mux_t *, sout_input_t * );
+static int Mux ( sout_mux_t * );
/* Reserve a pid and return it */
-static int AllocatePID( sout_mux_t *p_mux )
+static int AllocatePID( sout_mux_sys_t *p_sys )
{
- return( ++p_mux->i_pid_free );
+ return( ++p_sys->i_pid_free );
}
-static int GetPAT( sout_instance_t *p_sout, sout_buffer_t **pp_ts );
-static int GetPMT( sout_instance_t *p_sout, sout_buffer_t **pp_ts );
+static int GetPAT( sout_mux_t *p_mux, sout_buffer_t **pp_ts );
+static int GetPMT( sout_mux_t *p_mux, sout_buffer_t **pp_ts );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
- sout_instance_t *p_sout = (sout_instance_t*)p_this;
- sout_mux_t *p_mux;
+ sout_mux_t *p_mux =(sout_mux_t*)p_this;
+ sout_mux_sys_t *p_sys;
- msg_Info( p_sout, "Open" );
+ msg_Info( p_mux, "Open" );
- p_mux = malloc( sizeof( sout_mux_t ) );
+ p_sys = malloc( sizeof( sout_mux_sys_t ) );
- p_sout->pf_mux_capacity = Capability;
- p_sout->pf_mux_addstream = AddStream;
- p_sout->pf_mux_delstream = DelStream;
- p_sout->pf_mux = Mux;
- p_sout->p_mux_data = (void*)p_mux;
- p_sout->i_mux_preheader = 30; // really enough for a pes header
+ p_mux->pf_capacity = Capability;
+ p_mux->pf_addstream = AddStream;
+ p_mux->pf_delstream = DelStream;
+ p_mux->pf_mux = Mux;
+ p_mux->p_sys = p_sys;
+ p_mux->i_preheader = 30; // really enough for a pes header
srand( (uint32_t)mdate() );
- p_mux->i_stream_id_mpga = 0xc0;
- p_mux->i_stream_id_a52 = 0x80;
- p_mux->i_stream_id_mpgv = 0xe0;
+ p_sys->i_stream_id_mpga = 0xc0;
+ p_sys->i_stream_id_a52 = 0x80;
+ p_sys->i_stream_id_mpgv = 0xe0;
- p_mux->i_audio_bound = 0;
- p_mux->i_video_bound = 0;
+ p_sys->i_audio_bound = 0;
+ p_sys->i_video_bound = 0;
- p_mux->i_pat_version_number = rand() % 32;
- p_mux->pat.i_pid = 0;
- p_mux->pat.i_continuity_counter = 0;
+ p_sys->i_pat_version_number = rand() % 32;
+ p_sys->pat.i_pid = 0;
+ p_sys->pat.i_continuity_counter = 0;
- p_mux->i_pmt_version_number = rand() % 32;
- p_mux->pmt.i_pid = 0x10;
- p_mux->pmt.i_continuity_counter = 0;
+ p_sys->i_pmt_version_number = rand() % 32;
+ p_sys->pmt.i_pid = 0x10;
+ p_sys->pmt.i_continuity_counter = 0;
- p_mux->i_pid_free = 0x11;
- p_mux->i_pcr_pid = 0x1fff;
+ p_sys->i_pid_free = 0x11;
+ p_sys->i_pcr_pid = 0x1fff;
- p_mux->i_mpeg4_streams = 0;
+ p_sys->i_mpeg4_streams = 0;
return VLC_SUCCESS;
}
static void Close( vlc_object_t * p_this )
{
- sout_instance_t *p_sout = (sout_instance_t*)p_this;
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
+ sout_mux_t *p_mux = (sout_mux_t*)p_this;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
- msg_Info( p_sout, "Close" );
+ msg_Info( p_mux, "Close" );
- free( p_mux );
- p_sout->p_mux_data = NULL;
+ free( p_sys );
+ p_mux->p_sys = NULL;
}
-static int Capability( sout_instance_t *p_sout, int i_query, void *p_args, void *p_answer )
+static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, void *p_answer )
{
switch( i_query )
{
}
}
-static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
+static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
ts_stream_t *p_stream;
BITMAPINFOHEADER *p_bih;
WAVEFORMATEX *p_wf;
- msg_Dbg( p_sout, "adding input" );
- p_input->p_mux_data = (void*)p_stream = malloc( sizeof( ts_stream_t ) );
+ msg_Dbg( p_mux, "adding input" );
+ p_input->p_sys = (void*)p_stream = malloc( sizeof( ts_stream_t ) );
- p_stream->i_pid = AllocatePID( p_mux );
- if( p_mux->i_pcr_pid == 0x1fff )
+ p_stream->i_pid = AllocatePID( p_sys );
+ if( p_sys->i_pcr_pid == 0x1fff )
{
- p_mux->i_pcr_pid = p_stream->i_pid;
+ p_sys->i_pcr_pid = p_stream->i_pid;
}
p_stream->i_continuity_counter = 0;
{
case VLC_FOURCC( 'm', 'p','g', 'v' ):
p_stream->i_stream_type = 0x02;
- p_stream->i_stream_id = p_mux->i_stream_id_mpgv;
- p_mux->i_stream_id_mpgv++;
+ p_stream->i_stream_id = p_sys->i_stream_id_mpgv;
+ p_sys->i_stream_id_mpgv++;
break;
case VLC_FOURCC( 'm', 'p','4', 'v' ):
p_stream->i_stream_type = 0x10;
p_stream->i_stream_id = 0xfa;
- p_mux->i_mpeg4_streams++;
+ p_sys->i_mpeg4_streams++;
p_stream->i_es_id = p_stream->i_pid;
p_stream->i_sl_predefined = 0x01; // NULL SL header
break;
default:
return( -1 );
}
- p_mux->i_video_bound++;
+ p_sys->i_video_bound++;
p_bih = (BITMAPINFOHEADER*)p_input->input_format.p_format;
if( p_bih )
{
case VLC_FOURCC( 'a', '5','2', ' ' ):
case VLC_FOURCC( 'a', '5','2', 'b' ):
p_stream->i_stream_type = 0x81;
- p_stream->i_stream_id = p_mux->i_stream_id_a52;
- p_mux->i_stream_id_a52++;
+ p_stream->i_stream_id = p_sys->i_stream_id_a52;
+ p_sys->i_stream_id_a52++;
break;
case VLC_FOURCC( 'm', 'p','4', 'a' ):
p_stream->i_stream_type = 0x11;
p_stream->i_stream_id = 0xfa;
- p_mux->i_mpeg4_streams++;
+ p_sys->i_mpeg4_streams++;
p_stream->i_es_id = p_stream->i_pid;
p_stream->i_sl_predefined = 0x01; // NULL SL header
break;
case VLC_FOURCC( 'm', 'p','g', 'a' ):
p_stream->i_stream_type = 0x04;
- p_stream->i_stream_id = p_mux->i_stream_id_mpga;
- p_mux->i_stream_id_mpga++;
+ p_stream->i_stream_id = p_sys->i_stream_id_mpga;
+ p_sys->i_stream_id_mpga++;
break;
default:
return( -1 );
}
- p_mux->i_audio_bound++;
+ p_sys->i_audio_bound++;
p_wf = (WAVEFORMATEX*)p_input->input_format.p_format;
if( p_wf && p_wf->cbSize > 0 )
{
return( -1 );
}
- p_mux->i_ts_packet = 0; // force pat/pmt recreation
- p_mux->i_pat_version_number++; p_mux->i_pat_version_number %= 32;
- p_mux->i_pmt_version_number++; p_mux->i_pmt_version_number %= 32;
+ p_sys->i_ts_packet = 0; // force pat/pmt recreation
+ p_sys->i_pat_version_number++; p_sys->i_pat_version_number %= 32;
+ p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
return( 0 );
}
-static int DelStream( sout_instance_t *p_sout, sout_input_t *p_input )
+static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
- ts_stream_t *p_stream;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
+ ts_stream_t *p_stream;
- msg_Dbg( p_sout, "removing input" );
- p_stream = (ts_stream_t*)p_input->p_mux_data;
+ msg_Dbg( p_mux, "removing input" );
+ p_stream = (ts_stream_t*)p_input->p_sys;
if( p_stream->p_decoder_specific_info )
{
}
if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
{
- p_mux->i_mpeg4_streams--;
+ p_sys->i_mpeg4_streams--;
}
- p_mux->i_ts_packet = 0; // force pat/pmt recreation
- p_mux->i_pat_version_number++; p_mux->i_pat_version_number %= 32;
- p_mux->i_pmt_version_number++; p_mux->i_pmt_version_number %= 32;
+ p_sys->i_ts_packet = 0; // force pat/pmt recreation
+ p_sys->i_pat_version_number++; p_sys->i_pat_version_number %= 32;
+ p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
return( 0 );
}
-static int MuxGetStream( sout_instance_t *p_sout,
+static int MuxGetStream( sout_mux_t *p_mux,
int *pi_stream,
mtime_t *pi_dts )
{
int i_stream;
int i;
- for( i = 0, i_dts = 0, i_stream = -1; i < p_sout->i_nb_inputs; i++ )
+ for( i = 0, i_dts = 0, i_stream = -1; i < p_mux->i_nb_inputs; i++ )
{
sout_fifo_t *p_fifo;
- p_fifo = p_sout->pp_inputs[i]->p_fifo;
+ p_fifo = p_mux->pp_inputs[i]->p_fifo;
if( p_fifo->i_depth > 1 )
{
}
}
-static int Mux( sout_instance_t *p_sout )
+static int Mux( sout_mux_t *p_mux )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
int i_stream;
sout_buffer_t *p_pat, *p_pmt, *p_ts;
sout_fifo_t *p_fifo;
sout_buffer_t *p_data;
- if( MuxGetStream( p_sout, &i_stream, &i_dts ) < 0 )
+ if( MuxGetStream( p_mux, &i_stream, &i_dts ) < 0 )
{
return( 0 );
}
- p_input = p_sout->pp_inputs[i_stream];
+ p_input = p_mux->pp_inputs[i_stream];
p_fifo = p_input->p_fifo;
- p_stream = (ts_stream_t*)p_input->p_mux_data;
+ p_stream = (ts_stream_t*)p_input->p_sys;
p_data = sout_FifoGet( p_fifo );
i_dts = p_data->i_dts;
i_length = p_data->i_length;
- E_( EStoPES )( p_sout, &p_data, p_data, p_stream->i_stream_id, 1);
- PEStoTS( p_sout, &p_data, p_data, p_stream );
+ E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1);
+ PEStoTS( p_mux->p_sout, &p_data, p_data, p_stream );
- if( p_mux->i_ts_packet % 30 == 0 )
+ if( p_sys->i_ts_packet % 30 == 0 )
{
/* create pat/pmt */
- GetPAT( p_sout, &p_pat );
- GetPMT( p_sout, &p_pmt );
+ GetPAT( p_mux, &p_pat );
+ GetPMT( p_mux, &p_pmt );
p_ts = p_pat;
sout_BufferChain( &p_ts, p_pmt );
p_ts = p_data;
}
- p_mux->i_ts_packet++;
+ p_sys->i_ts_packet++;
SetTSDate( p_ts, i_dts, i_length );
- sout_AccessOutWrite( p_sout->p_access, p_ts );
+ sout_AccessOutWrite( p_mux->p_access, p_ts );
}
return( 0 );
}
#if defined MODULE_NAME_IS_mux_ts
-static int GetPAT( sout_instance_t *p_sout,
+static int GetPAT( sout_mux_t *p_mux,
sout_buffer_t **pp_ts )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
sout_buffer_t *p_pat;
bits_buffer_t bits;
- p_pat = sout_BufferNew( p_sout, 1024 );
+ p_pat = sout_BufferNew( p_mux->p_sout, 1024 );
p_pat->i_pts = 0;
p_pat->i_dts = 0;
bits_write( &bits, 12, 13 ); // XXX for one program only XXX
bits_write( &bits, 16, 0x01 ); // FIXME stream id
bits_write( &bits, 2, 0x03 ); // FIXME
- bits_write( &bits, 5, p_mux->i_pat_version_number );
+ bits_write( &bits, 5, p_sys->i_pat_version_number );
bits_write( &bits, 1, 1 ); // current_next_indicator
bits_write( &bits, 8, 0 ); // section number
bits_write( &bits, 8, 0 ); // last section number
bits_write( &bits, 16, 1 ); // program number
bits_write( &bits, 3, 0x07 ); // reserved
- bits_write( &bits, 13, p_mux->pmt.i_pid ); // program map pid
+ bits_write( &bits, 13, p_sys->pmt.i_pid ); // program map pid
bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
p_pat->i_size = bits.i_data;
- return( PEStoTS( p_sout, pp_ts, p_pat, &p_mux->pat ) );
+ return( PEStoTS( p_mux->p_sout, pp_ts, p_pat, &p_sys->pat ) );
}
-static int GetPMT( sout_instance_t *p_sout,
+static int GetPMT( sout_mux_t *p_mux,
sout_buffer_t **pp_ts )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
sout_buffer_t *p_pmt;
bits_buffer_t bits;
int i_stream;
- p_pmt = sout_BufferNew( p_sout, 1024 );
+ p_pmt = sout_BufferNew( p_mux->p_sout, 1024 );
p_pmt->i_pts = 0;
p_pmt->i_dts = 0;
bits_write( &bits, 1, 1 ); // section_syntax_indicator
bits_write( &bits, 1, 0 ); // 0
bits_write( &bits, 2, 0 ); // reserved FIXME
- bits_write( &bits, 12, 13 + 5 * p_sout->i_nb_inputs );
+ bits_write( &bits, 12, 13 + 5 * p_mux->i_nb_inputs );
bits_write( &bits, 16, 1 ); // FIXME program number
bits_write( &bits, 2, 0 ); // FIXME
- bits_write( &bits, 5, p_mux->i_pmt_version_number );
+ bits_write( &bits, 5, p_sys->i_pmt_version_number );
bits_write( &bits, 1, 0 ); // current_next_indicator
bits_write( &bits, 8, 0 ); // section number
bits_write( &bits, 8, 0 ); // last section number
bits_write( &bits, 3, 0 ); // reserved
- bits_write( &bits, 13, p_mux->i_pcr_pid ); // FIXME FXIME PCR_PID FIXME
+ bits_write( &bits, 13, p_sys->i_pcr_pid ); // FIXME FXIME PCR_PID FIXME
bits_write( &bits, 4, 0 ); // reserved FIXME
bits_write( &bits, 12, 0 ); // program info len FIXME
- for( i_stream = 0; i_stream < p_sout->i_nb_inputs; i_stream++ )
+ for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
{
ts_stream_t *p_stream;
- p_stream = (ts_stream_t*)p_sout->pp_inputs[i_stream]->p_mux_data;
+ p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
bits_write( &bits, 8, p_stream->i_stream_type ); // stream_type
bits_write( &bits, 3, 0 ); // reserved
p_pmt->i_size = bits.i_data;
- return( PEStoTS( p_sout, pp_ts, p_pmt, &p_mux->pmt ) );
+ return( PEStoTS( p_mux->p_sout, pp_ts, p_pmt, &p_sys->pmt ) );
}
#elif defined MODULE_NAME_IS_mux_ts_dvbpsi
return( p_first );
}
-static int GetPAT( sout_instance_t *p_sout,
+static int GetPAT( sout_mux_t *p_mux,
sout_buffer_t **pp_ts )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
sout_buffer_t *p_pat;
dvbpsi_pat_t pat;
dvbpsi_psi_section_t *p_section;
dvbpsi_InitPAT( &pat,
0x01, // i_ts_id
- p_mux->i_pat_version_number,
+ p_sys->i_pat_version_number,
0); // b_current_next
/* add all program (only one) */
dvbpsi_PATAddProgram( &pat,
1, // i_number
- p_mux->pmt.i_pid ); // i_pid
+ p_sys->pmt.i_pid ); // i_pid
p_section = dvbpsi_GenPATSections( &pat,
0 ); // max program per section
- p_pat = WritePSISection( p_sout, p_section );
+ p_pat = WritePSISection( p_mux->p_sout, p_section );
- PEStoTS( p_sout, pp_ts, p_pat, &p_mux->pat );
+ PEStoTS( p_mux->p_sout, pp_ts, p_pat, &p_sys->pat );
dvbpsi_DeletePSISections( p_section );
dvbpsi_EmptyPAT( &pat );
return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );
}
-static int GetPMT( sout_instance_t *p_sout,
+static int GetPMT( sout_mux_t *p_mux,
sout_buffer_t **pp_ts )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
- sout_buffer_t *p_pmt;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
+ sout_buffer_t *p_pmt;
dvbpsi_pmt_t pmt;
- dvbpsi_pmt_es_t* p_es;
+ dvbpsi_pmt_es_t *p_es;
dvbpsi_psi_section_t *p_section;
int i_stream;
dvbpsi_InitPMT( &pmt,
0x01, // program number
- p_mux->i_pmt_version_number,
+ p_sys->i_pmt_version_number,
1, // b_current_next
- p_mux->i_pcr_pid );
+ p_sys->i_pcr_pid );
- if( p_mux->i_mpeg4_streams > 0 )
+ if( p_sys->i_mpeg4_streams > 0 )
{
uint8_t iod[4096];
bits_buffer_t bits;
bits_write( &bits, 8, 0xfe ); // audioProfile (unspecified)
bits_write( &bits, 8, 0xfe ); // visualProfile( // )
bits_write( &bits, 8, 0xff ); // graphicProfile (no )
- for( i_stream = 0; i_stream < p_sout->i_nb_inputs; i_stream++ )
+ for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
{
ts_stream_t *p_stream;
- p_stream = (ts_stream_t*)p_sout->pp_inputs[i_stream]->p_mux_data;
+ p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
{
bits_write( &bits, 8, 0x00 );
bits_write( &bits, 6, 0x00 );
- msg_Err( p_sout,"Unsupported stream_type => broken IOD");
+ msg_Err( p_mux->p_sout,"Unsupported stream_type => broken IOD");
}
bits_write( &bits, 1, 0x00 ); // UpStream
bits_write( &bits, 1, 0x01 ); // reserved
bits_align( &bits );
break;
default:
- msg_Err( p_sout,"Unsupported SL profile => broken IOD");
+ msg_Err( p_mux,"Unsupported SL profile => broken IOD");
break;
}
/* fix ESDescr length */
bits.p_data );
}
- for( i_stream = 0; i_stream < p_sout->i_nb_inputs; i_stream++ )
+ for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
{
ts_stream_t *p_stream;
- p_stream = (ts_stream_t*)p_sout->pp_inputs[i_stream]->p_mux_data;
+ p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;
p_es = dvbpsi_PMTAddES( &pmt,
p_stream->i_stream_type,
p_section = dvbpsi_GenPMTSections( &pmt );
- p_pmt = WritePSISection( p_sout, p_section );
+ p_pmt = WritePSISection( p_mux->p_sout, p_section );
- PEStoTS( p_sout, pp_ts, p_pmt, &p_mux->pmt );
+ PEStoTS( p_mux->p_sout, pp_ts, p_pmt, &p_sys->pmt );
dvbpsi_DeletePSISections( p_section );
dvbpsi_EmptyPMT( &pmt );
* ogg.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: ogg.c,v 1.2 2003/02/25 17:17:43 fenrir Exp $
+ * $Id: ogg.c,v 1.3 2003/03/11 19:02:30 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
-static int Capability( sout_instance_t *, int, void *, void * );
-static int AddStream( sout_instance_t *, sout_input_t * );
-static int DelStream( sout_instance_t *, sout_input_t * );
-static int Mux ( sout_instance_t * );
+static int Capability(sout_mux_t *, int, void *, void * );
+static int AddStream( sout_mux_t *, sout_input_t * );
+static int DelStream( sout_mux_t *, sout_input_t * );
+static int Mux ( sout_mux_t * );
/*****************************************************************************
* Module descriptor
} ogg_stream_t;
-typedef struct sout_mux_s
+struct sout_mux_sys_t
{
int b_write_header;
int i_streams;
-} sout_mux_t;
+};
#define SetWLE( p, v ) _SetWLE( (uint8_t*)p, v)
static void _SetWLE( uint8_t *p, uint16_t i_dw )
}
static void OggSetDate( sout_buffer_t *, mtime_t , mtime_t );
-static sout_buffer_t *OggStreamFlush( sout_instance_t *, ogg_stream_state *, mtime_t );
+static sout_buffer_t *OggStreamFlush( sout_mux_t *, ogg_stream_state *, mtime_t );
/*****************************************************************************
* Open:
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
- sout_instance_t *p_sout = (sout_instance_t*)p_this;
- sout_mux_t *p_mux;
+ sout_mux_t *p_mux = (sout_mux_t*)p_this;
+ sout_mux_sys_t *p_sys;
- msg_Info( p_sout, "Open" );
+ msg_Info( p_mux, "Open" );
- p_mux = malloc( sizeof( sout_mux_t ) );
- p_mux->i_streams = 0;
- p_mux->b_write_header = VLC_TRUE;
+ p_sys = malloc( sizeof( sout_mux_sys_t ) );
+ p_sys->i_streams = 0;
+ p_sys->b_write_header = VLC_TRUE;
- p_sout->p_mux_data = (void*)p_mux;
- p_sout->pf_mux_capacity = Capability;
- p_sout->pf_mux_addstream = AddStream;
- p_sout->pf_mux_delstream = DelStream;
- p_sout->pf_mux = Mux;
- p_sout->i_mux_preheader = 1;
+ p_mux->p_sys = p_sys;
+ p_mux->pf_capacity = Capability;
+ p_mux->pf_addstream = AddStream;
+ p_mux->pf_delstream = DelStream;
+ p_mux->pf_mux = Mux;
+ p_mux->i_preheader = 1;
return VLC_SUCCESS;
}
static void Close( vlc_object_t * p_this )
{
- sout_instance_t *p_sout = (sout_instance_t*)p_this;
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
+ sout_mux_t *p_mux = (sout_mux_t*)p_this;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
- msg_Info( p_sout, "Close" );
+ msg_Info( p_mux, "Close" );
- free( p_mux );
+ free( p_sys );
}
-static int Capability( sout_instance_t *p_sout, int i_query, void *p_args, void *p_answer )
+static int Capability( sout_mux_t *p_mux, int i_query, void *p_args, void *p_answer )
{
switch( i_query )
{
}
}
-static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
+static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
ogg_stream_t *p_stream;
BITMAPINFOHEADER *p_bih;
WAVEFORMATEX *p_wf;
- msg_Dbg( p_sout, "adding input" );
- p_input->p_mux_data = (void*)p_stream = malloc( sizeof( ogg_stream_t ) );
+ msg_Dbg( p_mux, "adding input" );
+ p_input->p_sys = (void*)p_stream = malloc( sizeof( ogg_stream_t ) );
p_stream->i_cat = p_input->input_format.i_cat;
p_stream->i_fourcc = p_input->input_format.i_fourcc;
}
break;
default:
- FREE( p_input->p_mux_data );
+ FREE( p_input->p_sys );
return( VLC_EGENERIC );
}
break;
break;
case VLC_FOURCC( 'v', 'o', 'r', 'b' ):
default:
- FREE( p_input->p_mux_data );
+ FREE( p_input->p_sys );
return( VLC_EGENERIC );
}
break;
default:
- FREE( p_input->p_mux_data );
+ FREE( p_input->p_sys );
return( VLC_EGENERIC );
}
ogg_stream_init (&p_stream->os, rand ());
- p_mux->i_streams++;
+ p_sys->i_streams++;
return( VLC_SUCCESS );
}
-static int DelStream( sout_instance_t *p_sout, sout_input_t *p_input )
+static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
{
- ogg_stream_t *p_stream = (ogg_stream_t*)p_input->p_mux_data;
+ ogg_stream_t *p_stream = (ogg_stream_t*)p_input->p_sys;
sout_buffer_t *p_og;
- msg_Dbg( p_sout, "removing input" );
+ msg_Dbg( p_mux, "removing input" );
/* flush all remaining data */
- p_og = OggStreamFlush( p_sout, &p_stream->os, 0 );
+ p_og = OggStreamFlush( p_mux, &p_stream->os, 0 );
if( p_og )
{
OggSetDate( p_og, p_stream->i_dts, p_stream->i_length );
- sout_AccessOutWrite( p_sout->p_access, p_og );
+ sout_AccessOutWrite( p_mux->p_access, p_og );
}
ogg_stream_clear( &p_stream->os );
- FREE( p_input->p_mux_data );
+ FREE( p_input->p_sys );
return( 0 );
}
/*
* TODO move this function to src/stream_output.c (used by nearly all muxers)
*/
-static int MuxGetStream( sout_instance_t *p_sout,
+static int MuxGetStream( sout_mux_t *p_mux,
int *pi_stream,
mtime_t *pi_dts )
{
int i_stream;
int i;
- for( i = 0, i_dts = 0, i_stream = -1; i < p_sout->i_nb_inputs; i++ )
+ for( i = 0, i_dts = 0, i_stream = -1; i < p_mux->i_nb_inputs; i++ )
{
sout_fifo_t *p_fifo;
- p_fifo = p_sout->pp_inputs[i]->p_fifo;
+ p_fifo = p_mux->pp_inputs[i]->p_fifo;
if( p_fifo->i_depth > 1 )
{
}
-static sout_buffer_t *OggStreamFlush( sout_instance_t *p_sout,
+static sout_buffer_t *OggStreamFlush( sout_mux_t *p_mux,
ogg_stream_state *p_os,
mtime_t i_pts )
{
break;
}
i_size = og.header_len + og.body_len;
- p_og = sout_BufferNew( p_sout, i_size);
+ p_og = sout_BufferNew( p_mux->p_sout, i_size);
memcpy( p_og->p_buffer,
og.header,
return( p_og_first );
}
-static sout_buffer_t *OggStreamPageOut( sout_instance_t *p_sout,
+static sout_buffer_t *OggStreamPageOut( sout_mux_t *p_mux,
ogg_stream_state *p_os,
mtime_t i_pts )
{
break;
}
i_size = og.header_len + og.body_len;
- p_og = sout_BufferNew( p_sout, i_size);
+ p_og = sout_BufferNew( p_mux->p_sout, i_size);
memcpy( p_og->p_buffer,
og.header,
return( p_og_first );
}
-static sout_buffer_t *OggCreateHeader( sout_instance_t *p_sout, mtime_t i_dts )
+static sout_buffer_t *OggCreateHeader( sout_mux_t *p_mux, mtime_t i_dts )
{
sout_buffer_t *p_hdr = NULL;
sout_buffer_t *p_og;
int i;
/* write header for each stream */
- for( i = 0; i < p_sout->i_nb_inputs; i++ )
+ for( i = 0; i < p_mux->i_nb_inputs; i++ )
{
ogg_stream_t *p_stream;
- p_stream = (ogg_stream_t*)p_sout->pp_inputs[i]->p_mux_data;
+ p_stream = (ogg_stream_t*)p_mux->pp_inputs[i]->p_sys;
if( p_stream->i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
{
#endif
}
- p_og = OggStreamFlush( p_sout, &p_stream->os, 0 );
+ p_og = OggStreamFlush( p_mux, &p_stream->os, 0 );
sout_BufferChain( &p_hdr, p_og );
}
}
}
-static int Mux ( sout_instance_t *p_sout )
+static int Mux ( sout_mux_t *p_mux )
{
- sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
+ sout_mux_sys_t *p_sys = p_mux->p_sys;
sout_buffer_t *p_og = NULL;
int i_stream;
mtime_t i_dts;
- if( p_mux->b_write_header )
+ if( p_sys->b_write_header )
{
- if( MuxGetStream( p_sout, &i_stream, &i_dts) < 0 )
+ if( MuxGetStream( p_mux, &i_stream, &i_dts) < 0 )
{
return( VLC_SUCCESS );
}
- sout_BufferChain( &p_og, OggCreateHeader( p_sout, i_dts ) );
- p_mux->b_write_header = VLC_FALSE;
+ sout_BufferChain( &p_og, OggCreateHeader( p_mux, i_dts ) );
+ p_sys->b_write_header = VLC_FALSE;
}
for( ;; )
sout_buffer_t *p_data;
ogg_packet op;
- if( MuxGetStream( p_sout, &i_stream, &i_dts) < 0 )
+ if( MuxGetStream( p_mux, &i_stream, &i_dts) < 0 )
{
return( VLC_SUCCESS );
}
- p_input = p_sout->pp_inputs[i_stream];
- p_stream = (ogg_stream_t*)p_input->p_mux_data;
+ p_input = p_mux->pp_inputs[i_stream];
+ p_stream = (ogg_stream_t*)p_input->p_sys;
p_data = sout_FifoGet( p_input->p_fifo );
- sout_BufferReallocFromPreHeader( p_sout, p_data, 1 );
+ sout_BufferReallocFromPreHeader( p_mux->p_sout, p_data, 1 );
p_data->p_buffer[0] = PACKET_IS_SYNCPOINT; // FIXME
op.packet = p_data->p_buffer;
ogg_stream_packetin( &p_stream->os, &op );
sout_BufferChain( &p_og,
- OggStreamPageOut( p_sout,
+ OggStreamPageOut( p_mux,
&p_stream->os,
p_data->i_pts ) );
OggSetDate( p_og, p_stream->i_dts, p_stream->i_length );
p_stream->i_dts = -1;
p_stream->i_length = 0;;
- sout_AccessOutWrite( p_sout->p_access, p_og );
+ sout_AccessOutWrite( p_mux->p_access, p_og );
p_og = NULL;
}
p_stream->i_length += p_data->i_length;
}
- sout_BufferDelete( p_sout, p_data );
+ sout_BufferDelete( p_mux->p_sout, p_data );
}
return( VLC_SUCCESS );
* a52.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: a52.c,v 1.1 2002/12/14 21:32:41 fenrir Exp $
+ * $Id: a52.c,v 1.2 2003/03/11 19:02:30 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
bit_stream_t bit_stream;
/* Output properties */
- sout_input_t *p_sout_input;
+ sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format;
uint64_t i_samplescount;
* copy.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: copy.c,v 1.4 2003/01/23 15:52:04 sam Exp $
+ * $Id: copy.c,v 1.5 2003/03/11 19:02:30 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
decoder_fifo_t *p_fifo;
/* Output properties */
- sout_input_t *p_sout_input;
+ sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format;
mtime_t i_pts_start;
* mpeg4audio.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: mpeg4audio.c,v 1.2 2003/01/23 15:52:04 sam Exp $
+ * $Id: mpeg4audio.c,v 1.3 2003/03/11 19:02:31 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
bit_stream_t bit_stream;
/* Output properties */
- sout_input_t *p_sout_input;
+ sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format;
mtime_t i_pts_start;
* mpeg4video.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: mpeg4video.c,v 1.7 2003/01/23 15:52:04 sam Exp $
+ * $Id: mpeg4video.c,v 1.8 2003/03/11 19:02:31 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
decoder_fifo_t *p_fifo;
/* Output properties */
- sout_input_t *p_sout_input;
+ sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format;
mtime_t i_pts_start;
* mpegaudio.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: mpegaudio.c,v 1.3 2003/02/18 00:51:40 fenrir Exp $
+ * $Id: mpegaudio.c,v 1.4 2003/03/11 19:02:31 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
bit_stream_t bit_stream;
/* Output properties */
- sout_input_t *p_sout_input;
+ sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format;
uint64_t i_samplescount;
* mpegvideo.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
- * $Id: mpegvideo.c,v 1.9 2003/02/26 13:51:36 gbazin Exp $
+ * $Id: mpegvideo.c,v 1.10 2003/03/11 19:02:31 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
bit_stream_t bit_stream;
/* Output properties */
- sout_input_t *p_sout_input;
+ sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format;
mtime_t i_last_dts;
* stream_output.c : stream output module
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: stream_output.c,v 1.16 2003/02/25 17:17:43 fenrir Exp $
+ * $Id: stream_output.c,v 1.17 2003/03/11 19:02:31 fenrir Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Laurent Aimar <fenrir@via.ecp.fr>
- * Erioc Petit <titer@videolan.org>
+ * Eric Petit <titer@videolan.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
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static int InitInstance ( sout_instance_t * );
-
-struct sout_instance_sys_t
+static int InstanceNewOutput ( sout_instance_t *, char * );
+static int InstanceMuxNew ( sout_instance_t *,
+ char *, char *, char * );
+
+static sout_mux_t * MuxNew ( sout_instance_t*,
+ char *, sout_access_out_t * );
+static sout_input_t *MuxAddStream ( sout_mux_t *, sout_packet_format_t * );
+static void MuxDeleteStream ( sout_mux_t *, sout_input_t * );
+static void MuxDelete ( sout_mux_t * );
+
+#if 0
+typedef struct
{
/* if muxer doesn't support adding stream at any time then we first wait
* for stream then we refuse all stream and start muxing */
/* we wait one second after first stream added */
mtime_t i_add_stream_start;
+
+} sout_instance_sys_mux_t;
+#endif
+
+struct sout_instance_sys_t
+{
+ int i_d_u_m_m_y;
};
+/*
+ * Generic MRL parser
+ *
+ */
+/* <access>{options}/<way>{options}://<name> */
+typedef struct mrl_option_s
+{
+ struct mrl_option_s *p_next;
+
+ char *psz_name;
+ char *psz_value;
+} mrl_option_t;
+
+typedef struct
+{
+ char *psz_access;
+ mrl_option_t *p_access_options;
+
+ char *psz_way;
+ mrl_option_t *p_way_options;
+
+ char *psz_name;
+} mrl_t;
+
+/* mrl_Parse: parse psz_mrl and fill p_mrl */
+static int mrl_Parse( mrl_t *p_mrl, char *psz_mrl );
+/* mrl_Clean: clean p_mrl after a call to mrl_Parse */
+static void mrl_Clean( mrl_t *p_mrl );
+
+/* some macro */
+#define TAB_APPEND( count, tab, p ) \
+ if( (count) > 0 ) \
+ { \
+ (tab) = realloc( (tab), sizeof( void ** ) * ( (count) + 1 ) ); \
+ } \
+ else \
+ { \
+ (tab) = malloc( sizeof( void ** ) ); \
+ } \
+ (void**)(tab)[(count)] = (void*)(p); \
+ (count)++
+
+#define TAB_FIND( count, tab, p, index ) \
+ { \
+ int _i_; \
+ (index) = -1; \
+ for( _i_ = 0; _i_ < (count); _i_++ ) \
+ { \
+ if((void**)(tab)[_i_]==(void*)(p)) \
+ { \
+ (index) = _i_; \
+ break; \
+ } \
+ } \
+ }
+
+#define TAB_REMOVE( count, tab, p ) \
+ { \
+ int i_index; \
+ TAB_FIND( count, tab, p, i_index ); \
+ if( i_index >= 0 ) \
+ { \
+ if( count > 1 ) \
+ { \
+ memmove( ((void**)tab + i_index), \
+ ((void**)tab + i_index+1), \
+ ( (count) - i_index - 1 ) * sizeof( void* ) );\
+ } \
+ else \
+ { \
+ free( tab ); \
+ (tab) = NULL; \
+ } \
+ (count)--; \
+ } \
+ }
+
+#define FREE( p ) if( p ) { free( p ); (p) = NULL; }
/*****************************************************************************
* sout_NewInstance: creates a new stream output instance
sout_instance_t * __sout_NewInstance ( vlc_object_t *p_parent,
char * psz_dest )
{
- sout_instance_t * p_sout;
+ sout_instance_t *p_sout;
+ char *psz_dup, *psz_parser, *psz_pos;
/* Allocate descriptor */
p_sout = vlc_object_create( p_parent, VLC_OBJECT_SOUT );
return NULL;
}
- p_sout->psz_dest = strdup( psz_dest );
+ p_sout->psz_sout = NULL;
+
+ p_sout->i_nb_dest = 0;
+ p_sout->ppsz_dest = NULL;
- if ( InitInstance( p_sout ) == -1 )
+ p_sout->i_preheader = 0;
+ p_sout->i_nb_mux = 0;
+ p_sout->pp_mux = 0;
+
+ vlc_mutex_init( p_sout, &p_sout->lock );
+ p_sout->i_nb_inputs = 0;
+ p_sout->pp_inputs = NULL;
+
+ p_sout->p_sys = malloc( sizeof( sout_instance_sys_t ) );
+
+ /* now parse psz_sout */
+ psz_dup = strdup( psz_dest );
+ psz_parser = psz_dup;
+
+ while( ( psz_pos = strchr( psz_parser, '#' ) ) != NULL )
{
+ *psz_pos++ = '\0';
+
+ if( InstanceNewOutput( p_sout, psz_parser ) )
+ {
+ msg_Err( p_sout, "adding `%s' failed", psz_parser );
+ }
+
+ psz_parser = psz_pos;
+ }
+
+ if( *psz_parser )
+ {
+ if( InstanceNewOutput( p_sout, psz_parser ) )
+ {
+ msg_Err( p_sout, "adding `%s' failed", psz_parser );
+ }
+ }
+
+ free( psz_dup );
+
+ if( p_sout->i_nb_dest <= 0 )
+ {
+ msg_Err( p_sout, "all sout failed" );
vlc_object_destroy( p_sout );
- return NULL;
+ return( NULL );
}
vlc_object_attach( p_sout, p_parent );
return p_sout;
}
+/*****************************************************************************
+ * sout_DeleteInstance: delete a previously allocated instance
+ *****************************************************************************/
+void sout_DeleteInstance( sout_instance_t * p_sout )
+{
+ int i;
+ /* Unlink object */
+ vlc_object_detach( p_sout );
+
+ /* *** free all string *** */
+ FREE( p_sout->psz_sout );
+
+ for( i = 0; i < p_sout->i_nb_dest; i++ )
+ {
+ FREE( p_sout->ppsz_dest[i] );
+ }
+ FREE( p_sout->ppsz_dest );
+
+ /* *** there shouldn't be any input ** */
+ if( p_sout->i_nb_inputs > 0 )
+ {
+ msg_Err( p_sout, "i_nb_inputs=%d > 0 !!!!!!", p_sout->i_nb_inputs );
+ msg_Err( p_sout, "mmmh I have a bad filling...", p_sout->i_nb_inputs );
+ }
+ vlc_mutex_destroy( &p_sout->lock );
+
+ /* *** remove all muxer *** */
+ for( i = 0; i < p_sout->i_nb_mux; i++ )
+ {
+#define p_mux p_sout->pp_mux[i]
+ sout_AccessOutDelete( p_mux->p_access );
+ MuxDelete( p_mux );
+#undef p_mux
+ }
+ FREE( p_sout->pp_mux );
+
+#if 0
+ for( i = 0; i < p_sout->p_sys->i_nb_mux; i++ )
+ {
+ FREE( p_sout->p_sys->pp_mux[i] );
+ }
+ FREE( p_sout->p_sys->pp_mux );
+#endif
+
+ /* Free structure */
+ vlc_object_destroy( p_sout );
+}
+
+
/*****************************************************************************
* InitInstance: opens appropriate modules
*****************************************************************************/
-static int InitInstance( sout_instance_t * p_sout )
+static int InstanceNewOutput (sout_instance_t *p_sout, char *psz_dest )
{
+ mrl_t mrl;
+ char * psz_dup;
+#if 0
/* Parse dest string. Syntax : [[<access>][/<mux>]:][<dest>] */
/* This code is identical to input.c:InitThread. FIXME : factorize it ? */
- char * psz_parser = p_sout->psz_dest;
-
- p_sout->psz_access = "";
- p_sout->psz_mux = "";
- p_sout->psz_name = "";
- p_sout->p_access = NULL;
- p_sout->p_mux = NULL;
- p_sout->i_mux_preheader = 0;
- p_sout->i_nb_inputs = 0;
- p_sout->pp_inputs = NULL;
- vlc_mutex_init( p_sout, &p_sout->lock );
- p_sout->p_sys = malloc( sizeof( sout_instance_sys_t ) );
- /* fixed after opening muxer */
- p_sout->p_sys->b_add_stream_any_time = VLC_FALSE;
- p_sout->p_sys->b_waiting_stream = VLC_TRUE;
- p_sout->p_sys->i_add_stream_start = -1;
- /* Skip the plug-in names */
+ char * psz_dup = strdup( psz_dest );
+ char * psz_parser = psz_dup;
+ char * psz_access = "";
+ char * psz_mux = "";
+ char * psz_name = "";
+ /* *** first parse psz_dest */
while( *psz_parser && *psz_parser != ':' )
{
psz_parser++;
}
#if defined( WIN32 ) || defined( UNDER_CE )
- if( psz_parser - p_sout->psz_dest == 1 )
+ if( psz_parser - psz_dup == 1 )
{
msg_Warn( p_sout, "drive letter %c: found in source string",
- *p_sout->psz_dest ) ;
+ *psz_dup ) ;
psz_parser = "";
}
#endif
if( !*psz_parser )
{
- p_sout->psz_access = p_sout->psz_mux = "";
- p_sout->psz_name = p_sout->psz_dest;
+ psz_access = psz_mux = "";
+ psz_name = psz_dup;
}
else
{
if( psz_parser[0] == '/' && psz_parser[1] == '/' )
{
psz_parser += 2 ;
- }
+ }
- p_sout->psz_name = psz_parser ;
+ psz_name = psz_parser ;
/* Come back to parse the access and mux plug-ins */
- psz_parser = p_sout->psz_dest;
+ psz_parser = psz_dup;
if( !*psz_parser )
{
/* No access */
- p_sout->psz_access = "";
+ psz_access = "";
}
else if( *psz_parser == '/' )
{
/* No access */
- p_sout->psz_access = "";
+ psz_access = "";
psz_parser++;
}
else
{
- p_sout->psz_access = psz_parser;
+ psz_access = psz_parser;
while( *psz_parser && *psz_parser != '/' )
{
if( !*psz_parser )
{
/* No mux */
- p_sout->psz_mux = "";
+ psz_mux = "";
}
else
{
- p_sout->psz_mux = psz_parser;
+ psz_mux = psz_parser;
}
}
msg_Dbg( p_sout, "access `%s', mux `%s', name `%s'",
- p_sout->psz_access, p_sout->psz_mux, p_sout->psz_name );
+ psz_access, psz_mux, psz_name );
+#endif
+
+ mrl_Parse( &mrl, psz_dest );
+ msg_Dbg( p_sout, "access `%s', mux `%s', name `%s'",
+ mrl.psz_access, mrl.psz_way, mrl.psz_name );
+ vlc_mutex_lock( &p_sout->lock );
+ /* *** create mux *** */
- /* Find and open appropriate access module */
- p_sout->p_access =
- sout_AccessOutNew( p_sout, p_sout->psz_access, p_sout->psz_name );
- if( p_sout->p_access == NULL )
+ if( InstanceMuxNew( p_sout, mrl.psz_way, mrl.psz_access, mrl.psz_name ) )
{
- msg_Err( p_sout, "no suitable sout access module for `%s/%s://%s'",
- p_sout->psz_access, p_sout->psz_mux, p_sout->psz_name );
- return -1;
- }
-
+ msg_Err( p_sout, "cannot create sout chain for %s/%s://%s",
+ mrl.psz_access, mrl.psz_way, mrl.psz_name );
- /* Find and open appropriate mux module */
- p_sout->p_mux =
- module_Need( p_sout, "sout mux", p_sout->psz_mux );
+ mrl_Clean( &mrl );
+ vlc_mutex_unlock( &p_sout->lock );
+ return( VLC_EGENERIC );
+ }
+ mrl_Clean( &mrl );
- if( p_sout->p_mux == NULL )
+ /* *** finish all setup *** */
+ if( p_sout->psz_sout )
{
- msg_Err( p_sout, "no suitable mux module for `%s/%s://%s'",
- p_sout->psz_access, p_sout->psz_mux, p_sout->psz_name );
-
- sout_AccessOutDelete( p_sout->p_access );
- return -1;
+ p_sout->psz_sout =
+ realloc( p_sout->psz_sout,
+ strlen( p_sout->psz_sout ) +2+1+ strlen( psz_dest ) );
+ strcat( p_sout->psz_sout, "#" );
+ strcat( p_sout->psz_sout, psz_dest );
}
- if( p_sout->pf_mux_capacity )
+ else
{
- int b_answer;
- if( p_sout->pf_mux_capacity( p_sout,
- SOUT_MUX_CAP_GET_ADD_STREAM_ANY_TIME,
- NULL, (void*)&b_answer ) != SOUT_MUX_CAP_ERR_OK )
- {
- b_answer = VLC_FALSE;
- }
- if( b_answer )
- {
- msg_Dbg( p_sout, "muxer support adding stream at any time" );
- p_sout->p_sys->b_add_stream_any_time = VLC_TRUE;
- p_sout->p_sys->b_waiting_stream = VLC_FALSE;
- }
- else
- {
- p_sout->p_sys->b_add_stream_any_time = VLC_FALSE;
- p_sout->p_sys->b_waiting_stream = VLC_TRUE;
- }
+ p_sout->psz_sout = strdup( psz_dest );
}
- p_sout->i_nb_inputs = 0;
- p_sout->pp_inputs = NULL;
+ psz_dup = strdup( psz_dest );
+ TAB_APPEND( p_sout->i_nb_dest, p_sout->ppsz_dest, psz_dup );
+ vlc_mutex_unlock( &p_sout->lock );
- return 0;
-}
+ msg_Dbg( p_sout, "complete sout `%s'", p_sout->psz_sout );
+ return VLC_SUCCESS;
+}
-/*****************************************************************************
- * sout_DeleteInstance: delete a previously allocated instance
- *****************************************************************************/
-void sout_DeleteInstance( sout_instance_t * p_sout )
+static int InstanceMuxNew ( sout_instance_t *p_sout,
+ char *psz_mux, char *psz_access, char *psz_name )
{
- /* Unlink object */
- vlc_object_detach( p_sout );
- if( p_sout->p_mux )
+ sout_access_out_t *p_access;
+ sout_mux_t *p_mux;
+
+ /* *** find and open appropriate access module *** */
+ p_access =
+ sout_AccessOutNew( p_sout, psz_access, psz_name );
+ if( p_access == NULL )
{
- module_Unneed( p_sout, p_sout->p_mux );
+ msg_Err( p_sout, "no suitable sout access module for `%s/%s://%s'",
+ psz_access, psz_mux, psz_name );
+ return( VLC_EGENERIC );
}
- if( p_sout->p_access )
+
+ /* *** find and open appropriate mux module *** */
+ p_mux = MuxNew( p_sout, psz_mux, p_access );
+ if( p_mux == NULL )
{
- sout_AccessOutDelete( p_sout->p_access );
+ msg_Err( p_sout, "no suitable sout mux module for `%s/%s://%s'",
+ psz_access, psz_mux, psz_name );
+
+ sout_AccessOutDelete( p_access );
+ return( VLC_EGENERIC );
}
- vlc_mutex_destroy( &p_sout->lock );
+ p_sout->i_preheader = __MAX( p_sout->i_preheader,
+ p_mux->i_preheader );
+
+ TAB_APPEND( p_sout->i_nb_mux, p_sout->pp_mux, p_mux );
- /* Free structure */
- vlc_object_destroy( p_sout );
-}
+ return VLC_SUCCESS;
+}
/*****************************************************************************
* sout_AccessOutNew: allocate a new access out
*****************************************************************************/
if( !p_access->p_module )
{
+ free( p_access->psz_access );
+ free( p_access->psz_name );
vlc_object_destroy( p_access );
- p_access = NULL;
+ return( NULL );
}
return p_access;
+static sout_input_t *SoutInputCreate( sout_instance_t *p_sout,
+ sout_packet_format_t *p_format )
+{
+ sout_input_t *p_input;
+
+ p_input = malloc( sizeof( sout_input_t ) );
+
+ p_input->p_sout = p_sout;
+ memcpy( &p_input->input_format,
+ p_format,
+ sizeof( sout_packet_format_t ) );
+ p_input->p_fifo = sout_FifoCreate( p_sout );
+ p_input->p_sys = NULL;
+
+ return p_input;
+}
+
+static void SoutInputDestroy( sout_instance_t *p_sout,
+ sout_input_t *p_input )
+{
+ sout_FifoDestroy( p_sout, p_input->p_fifo );
+ free( p_input );
+}
+
+/*****************************************************************************
+ * Mux*: create/destroy/manipulate muxer.
+ * XXX: for now they are private, but I will near export them
+ * to allow muxer creating private muxer (ogg in avi, flexmux in ts/ps)
+ *****************************************************************************/
+
+/*****************************************************************************
+ * MuxNew: allocate a new mux
+ *****************************************************************************/
+static sout_mux_t * MuxNew ( sout_instance_t *p_sout,
+ char *psz_mux,
+ sout_access_out_t *p_access )
+{
+ sout_mux_t *p_mux;
+
+ p_mux = vlc_object_create( p_sout,
+ sizeof( sout_mux_t ) );
+ if( p_mux == NULL )
+ {
+ msg_Err( p_sout, "out of memory" );
+ return NULL;
+ }
+
+ p_mux->p_sout = p_sout;
+ p_mux->psz_mux = strdup( psz_mux);
+ p_mux->p_access = p_access;
+ p_mux->i_preheader = 0;
+ p_mux->pf_capacity = NULL;
+ p_mux->pf_addstream = NULL;
+ p_mux->pf_delstream = NULL;
+ p_mux->pf_mux = NULL;
+ p_mux->i_nb_inputs = 0;
+ p_mux->pp_inputs = NULL;
+
+ p_mux->p_sys = NULL;
+
+ p_mux->p_module = module_Need( p_mux,
+ "sout mux",
+ p_mux->psz_mux );
+ if( p_mux->p_module == NULL )
+ {
+ FREE( p_mux->psz_mux );
+
+ vlc_object_destroy( p_mux );
+ return NULL;
+ }
+
+ /* *** probe mux capacity *** */
+ if( p_mux->pf_capacity )
+ {
+ int b_answer;
+ if( p_mux->pf_capacity( p_mux,
+ SOUT_MUX_CAP_GET_ADD_STREAM_ANY_TIME,
+ NULL, (void*)&b_answer ) != SOUT_MUX_CAP_ERR_OK )
+ {
+ b_answer = VLC_FALSE;
+ }
+ if( b_answer )
+ {
+ msg_Dbg( p_sout, "muxer support adding stream at any time" );
+ p_mux->b_add_stream_any_time = VLC_TRUE;
+ p_mux->b_waiting_stream = VLC_FALSE;
+ }
+ else
+ {
+ p_mux->b_add_stream_any_time = VLC_FALSE;
+ p_mux->b_waiting_stream = VLC_TRUE;
+ }
+ }
+ else
+ {
+ p_mux->b_add_stream_any_time = VLC_FALSE;
+ p_mux->b_waiting_stream = VLC_TRUE;
+ }
+ p_mux->i_add_stream_start = -1;
+
+ return p_mux;
+}
+
+static void MuxDelete ( sout_mux_t *p_mux )
+{
+ if( p_mux->p_module )
+ {
+ module_Unneed( p_mux, p_mux->p_module );
+ }
+ free( p_mux->psz_mux );
+
+ vlc_object_destroy( p_mux );
+}
+
+static sout_input_t *MuxAddStream ( sout_mux_t *p_mux,
+ sout_packet_format_t *p_format )
+{
+ sout_input_t *p_input;
+
+ if( !p_mux->b_add_stream_any_time && !p_mux->b_waiting_stream)
+ {
+ msg_Err( p_mux, "cannot add a new stream (unsuported while muxing for this format)" );
+ return NULL;
+ }
+ if( p_mux->i_add_stream_start < 0 )
+ {
+ /* we wait for one second */
+ p_mux->i_add_stream_start = mdate();
+ }
+
+ msg_Dbg( p_mux, "adding a new input" );
+ /* create a new sout input */
+ p_input = SoutInputCreate( p_mux->p_sout, p_format );
+
+ TAB_APPEND( p_mux->i_nb_inputs, p_mux->pp_inputs, p_input );
+ if( p_mux->pf_addstream( p_mux, p_input ) < 0 )
+ {
+ msg_Err( p_mux, "cannot add this stream" );
+ MuxDeleteStream( p_mux, p_input );
+ return( NULL );
+ }
+
+ return( p_input );
+}
+
+static void MuxDeleteStream ( sout_mux_t *p_mux,
+ sout_input_t *p_input )
+{
+ int i_index;
+
+ TAB_FIND( p_mux->i_nb_inputs, p_mux->pp_inputs, p_input, i_index );
+ if( i_index >= 0 )
+ {
+ if( p_mux->pf_delstream( p_mux, p_input ) < 0 )
+ {
+ msg_Err( p_mux, "cannot del this stream from mux" );
+ }
+
+ /* remove the entry */
+ TAB_REMOVE( p_mux->i_nb_inputs, p_mux->pp_inputs, p_input );
+
+ if( p_mux->i_nb_inputs == 0 )
+ {
+ msg_Warn( p_mux, "no more input stream for this mux" );
+ }
+
+ SoutInputDestroy( p_mux->p_sout, p_input );
+ }
+}
+
+static void MuxSendBuffer ( sout_mux_t *p_mux,
+ sout_input_t *p_input,
+ sout_buffer_t *p_buffer )
+{
+ sout_FifoPut( p_input->p_fifo, p_buffer );
+
+ if( p_mux->b_waiting_stream )
+ {
+ if( p_mux->i_add_stream_start > 0 &&
+ p_mux->i_add_stream_start + (mtime_t)1000000 < mdate() )
+ {
+ /* more than 1 second, start muxing */
+ p_mux->b_waiting_stream = VLC_FALSE;
+ }
+ else
+ {
+ return;
+ }
+ }
+ p_mux->pf_mux( p_mux );
+}
+
/*****************************************************************************
*
*****************************************************************************/
-sout_input_t *__sout_InputNew( vlc_object_t *p_this,
- sout_packet_format_t *p_format )
+sout_packetizer_input_t *__sout_InputNew( vlc_object_t *p_this,
+ sout_packet_format_t *p_format )
{
- sout_instance_t *p_sout = NULL;
- sout_input_t *p_input;
+ sout_instance_t *p_sout = NULL;
+ sout_packetizer_input_t *p_input;
int i_try;
+ int i_mux;
+ vlc_bool_t b_accepted = VLC_FALSE;
/* search an stream output */
for( i_try = 0; i_try < 12; i_try++ )
msg_Err( p_this, "cannot find any stream ouput" );
return( NULL );
}
- if( !p_sout->p_sys->b_add_stream_any_time && !p_sout->p_sys->b_waiting_stream)
- {
- msg_Err( p_sout, "cannot add a new stream (unsuported while muxing for this format)" );
- return( NULL );
- }
-
msg_Dbg( p_sout, "adding a new input" );
- if( p_sout->p_sys->i_add_stream_start < 0 )
- {
- /* we wait for one second */
- p_sout->p_sys->i_add_stream_start = mdate();
- }
- /* create a new sout input */
- p_input = malloc( sizeof( sout_input_t ) );
-
- p_input->p_sout = p_sout;
- vlc_mutex_init( p_sout, &p_input->lock );
+ /* *** create a packetizer input *** */
+ p_input = malloc( sizeof( sout_packetizer_input_t ) );
+ p_input->p_sout = p_sout;
+ p_input->i_nb_inputs = 0;
+ p_input->pp_inputs = NULL;
+ p_input->i_nb_mux = 0;
+ p_input->pp_mux = NULL;
memcpy( &p_input->input_format,
p_format,
sizeof( sout_packet_format_t ) );
- p_input->p_fifo = sout_FifoCreate( p_sout );
- p_input->p_mux_data = NULL;
- if( p_input->input_format.i_fourcc != VLC_FOURCC( 'n', 'u', 'l', 'l' ) )
+ if( p_format->i_fourcc == VLC_FOURCC( 'n', 'u', 'l', 'l' ) )
{
- /* add this new one to p_sout */
- vlc_mutex_lock( &p_sout->lock );
- if( p_sout->i_nb_inputs == 0 )
- {
- p_sout->pp_inputs = malloc( sizeof( sout_input_t * ) );
- }
- else
- {
- p_sout->pp_inputs = realloc( p_sout->pp_inputs,
- sizeof( sout_input_t * ) *
- ( p_sout->i_nb_inputs + 1 ) );
- }
- p_sout->pp_inputs[p_sout->i_nb_inputs] = p_input;
- p_sout->i_nb_inputs++;
+ vlc_object_release( p_sout );
+ return p_input;
+ }
- if( p_sout->pf_mux_addstream( p_sout, p_input ) < 0 )
- {
- msg_Err( p_sout, "cannot add this stream" );
+ vlc_mutex_lock( &p_sout->lock );
+ /* *** add this input to all muxers *** */
+ for( i_mux = 0; i_mux < p_sout->i_nb_mux; i_mux++ )
+ {
+ sout_input_t *p_mux_input;
+#define p_mux p_sout->pp_mux[i_mux]
- vlc_mutex_unlock( &p_sout->lock );
- sout_InputDelete( p_input );
- vlc_mutex_lock( &p_sout->lock );
+ p_mux_input = MuxAddStream( p_mux, p_format );
+ if( p_mux_input )
+ {
+ TAB_APPEND( p_input->i_nb_inputs, p_input->pp_inputs, p_mux_input );
+ TAB_APPEND( p_input->i_nb_mux, p_input->pp_mux, p_mux );
- p_input = NULL;
+ b_accepted = VLC_TRUE;
}
+#undef p_mux
+ }
+
+ if( !b_accepted )
+ {
+ /* all muxer refuse this stream, so delete it */
+ free( p_input );
+
vlc_mutex_unlock( &p_sout->lock );
+ vlc_object_release( p_sout );
+ return( NULL );
}
+ TAB_APPEND( p_sout->i_nb_inputs, p_sout->pp_inputs, p_input );
+ vlc_mutex_unlock( &p_sout->lock );
+
vlc_object_release( p_sout );
return( p_input );
}
-int sout_InputDelete( sout_input_t *p_input )
+int sout_InputDelete( sout_packetizer_input_t *p_input )
{
sout_instance_t *p_sout = p_input->p_sout;
int i_input;
-
msg_Dbg( p_sout, "removing an input" );
vlc_mutex_lock( &p_sout->lock );
- sout_FifoDestroy( p_sout, p_input->p_fifo );
- vlc_mutex_destroy( &p_input->lock );
-
- for( i_input = 0; i_input < p_sout->i_nb_inputs; i_input++ )
+ /* *** remove this input to all muxers *** */
+ for( i_input = 0; i_input < p_input->i_nb_inputs; i_input++ )
{
- if( p_sout->pp_inputs[i_input] == p_input )
- {
- break;
- }
+ MuxDeleteStream( p_input->pp_mux[i_input], p_input->pp_inputs[i_input] );
}
- if( i_input < p_sout->i_nb_inputs )
- {
- if( p_sout->pf_mux_delstream( p_sout, p_input ) < 0 )
- {
- msg_Err( p_sout, "cannot del this stream from mux" );
- }
- /* remove the entry */
- if( p_sout->i_nb_inputs > 1 )
- {
- memmove( &p_sout->pp_inputs[i_input],
- &p_sout->pp_inputs[i_input+1],
- (p_sout->i_nb_inputs - i_input - 1) * sizeof( sout_input_t*) );
- }
- else
- {
- free( p_sout->pp_inputs );
- }
- p_sout->i_nb_inputs--;
+ TAB_REMOVE( p_sout->i_nb_inputs, p_sout->pp_inputs, p_input );
- if( p_sout->i_nb_inputs == 0 )
- {
- msg_Warn( p_sout, "no more input stream" );
- }
- }
- else if( p_input->input_format.i_fourcc != VLC_FOURCC( 'n', 'u', 'l', 'l' ) )
- {
- msg_Err( p_sout, "cannot find the input to be deleted" );
- }
+ free( p_input->pp_inputs );
+ free( p_input->pp_mux );
free( p_input );
vlc_mutex_unlock( &p_sout->lock );
-
return( 0 );
}
-int sout_InputSendBuffer( sout_input_t *p_input, sout_buffer_t *p_buffer )
+int sout_InputSendBuffer( sout_packetizer_input_t *p_input, sout_buffer_t *p_buffer )
{
- sout_instance_sys_t *p_sys = p_input->p_sout->p_sys;
+// sout_instance_sys_t *p_sys = p_input->p_sout->p_sys;
/* msg_Dbg( p_input->p_sout,
"send buffer, size:%d", p_buffer->i_size ); */
- if( p_input->input_format.i_fourcc != VLC_FOURCC( 'n', 'u', 'l', 'l' ) )
+ if( p_input->input_format.i_fourcc != VLC_FOURCC( 'n', 'u', 'l', 'l' ) &&
+ p_input->i_nb_inputs > 0 )
{
- sout_FifoPut( p_input->p_fifo, p_buffer );
+ int i;
- if( p_sys->b_waiting_stream )
+ vlc_mutex_lock( &p_input->p_sout->lock );
+ for( i = 0; i < p_input->i_nb_inputs - 1; i++ )
{
- if( p_sys->i_add_stream_start > 0 &&
- p_sys->i_add_stream_start + (mtime_t)1000000 < mdate() )
- {
- /* more than 1 second, start muxing */
- p_sys->b_waiting_stream = VLC_FALSE;
- }
- else
- {
- return( 0 );
- }
+ sout_buffer_t *p_dup;
+
+ p_dup = sout_BufferDuplicate( p_input->p_sout, p_buffer );
+
+ MuxSendBuffer( p_input->pp_mux[i],
+ p_input->pp_inputs[i],
+ p_dup );
}
- vlc_mutex_lock( &p_input->p_sout->lock );
- p_input->p_sout->pf_mux( p_input->p_sout );
+ MuxSendBuffer( p_input->pp_mux[p_input->i_nb_inputs-1],
+ p_input->pp_inputs[p_input->i_nb_inputs-1],
+ p_buffer );
+
vlc_mutex_unlock( &p_input->p_sout->lock );
}
else
{
sout_BufferDelete( p_input->p_sout, p_buffer );
}
-
return( 0 );
}
sout_buffer_t *sout_BufferNew( sout_instance_t *p_sout, size_t i_size )
{
sout_buffer_t *p_buffer;
- size_t i_prehader;
+ size_t i_preheader;
#ifdef DEBUG_BUFFER
msg_Dbg( p_sout, "allocating an new buffer, size:%d", (uint32_t)i_size );
#endif
p_buffer = malloc( sizeof( sout_buffer_t ) );
- i_prehader = p_sout->i_mux_preheader;
+ i_preheader = p_sout->i_preheader;
if( i_size > 0 )
{
- p_buffer->p_allocated_buffer = malloc( i_size + i_prehader );
- p_buffer->p_buffer = p_buffer->p_allocated_buffer + i_prehader;
+ p_buffer->p_allocated_buffer = malloc( i_size + i_preheader );
+ p_buffer->p_buffer = p_buffer->p_allocated_buffer + i_preheader;
}
else
{
p_buffer->p_allocated_buffer = NULL;
p_buffer->p_buffer = NULL;
}
- p_buffer->i_allocated_size = i_size + i_prehader;
+ p_buffer->i_allocated_size = i_size + i_preheader;
p_buffer->i_buffer_size = i_size;
p_buffer->i_size = i_size;
}
int sout_BufferRealloc( sout_instance_t *p_sout, sout_buffer_t *p_buffer, size_t i_size )
{
- size_t i_prehader;
+ size_t i_preheader;
#ifdef DEBUG_BUFFER
msg_Dbg( p_sout,
(uint32_t)i_size );
#endif
- i_prehader = p_buffer->p_buffer - p_buffer->p_allocated_buffer;
+ i_preheader = p_buffer->p_buffer - p_buffer->p_allocated_buffer;
- if( !( p_buffer->p_allocated_buffer = realloc( p_buffer->p_allocated_buffer, i_size + i_prehader ) ) )
+ if( !( p_buffer->p_allocated_buffer = realloc( p_buffer->p_allocated_buffer, i_size + i_preheader ) ) )
{
msg_Err( p_sout, "realloc failed" );
p_buffer->i_allocated_size = 0;
p_buffer->p_buffer = NULL;
return( -1 );
}
- p_buffer->p_buffer = p_buffer->p_allocated_buffer + i_prehader;
+ p_buffer->p_buffer = p_buffer->p_allocated_buffer + i_preheader;
- p_buffer->i_allocated_size = i_size + i_prehader;
+ p_buffer->i_allocated_size = i_size + i_preheader;
p_buffer->i_buffer_size = i_size;
return( 0 );
p->p_next = p_buffer;
}
}
+
+#if 0
+static int mrl_ParseOptions( mrl_option_t **pp_opt, char *psz_options )
+{
+ mrl_option_t **pp_last = pp_opt;
+
+ char *psz_parser = strdup( psz_options );
+
+ *pp_last = NULL;
+
+ if( *psz_parser == '=' )
+ {
+ free( psz_parser );
+ return( VLC_EGENERIC );
+ }
+ if( *psz_parser == '{' )
+ {
+ free( psz_parser );
+ }
+
+ for( ;; )
+ {
+ char *psz_end;
+ mrl_option_t opt;
+
+ /* skip space */
+ while( *psz_parser && ( *psz_parser == ' ' || *psz_parser == '\t' || *psz_parser == ';' ) )
+ {
+ psz_parser++;
+ }
+
+ if( ( psz_end = strchr( psz_parser, '=' ) ) != NULL )
+ {
+ opt.p_next = NULL;
+
+ while( psz_end > psz_parser && ( *psz_end == ' ' || *psz_end == '\t' ) )
+ {
+ psz_end--;
+ }
+
+ if( psz_end - psz_parser <= 0 )
+ {
+ return( VLC_EGENERIC );
+ }
+
+ *psz_end = '\0';
+ opt.psz_name = strdup( psz_parser );
+
+ psz_parser = psz_end + 1;
+ if( ( psz_end = strchr( psz_parser, ';' ) ) == NULL &&
+ ( psz_end = strchr( psz_parser, '}' ) ) == NULL )
+ {
+ psz_end = psz_parser + strlen( psz_parser ) + 1;
+ }
+
+ opt.psz_value = strdup( psz_parser );
+
+ fprintf( stderr, "option: name=`%s' value=`%s'\n",
+ opt.psz_name,
+ opt.psz_value );
+ psz_parser = psz_end + 1;
+
+ *pp_last = malloc( sizeof( mrl_option_t ) );
+ **pp_last = opt;
+ }
+ else
+ {
+ break;
+ }
+ }
+}
+#endif
+
+static int mrl_Parse( mrl_t *p_mrl, char *psz_mrl )
+{
+ char * psz_dup = strdupa( psz_mrl );
+ char * psz_parser = psz_dup;
+ char * psz_access = "";
+ char * psz_way = "";
+ char * psz_name = "";
+
+ /* *** first parse psz_dest */
+ while( *psz_parser && *psz_parser != ':' )
+ {
+ if( *psz_parser == '{' )
+ {
+ while( *psz_parser && *psz_parser != '}' )
+ {
+ psz_parser++;
+ }
+ if( *psz_parser )
+ {
+ psz_parser++;
+ }
+ }
+ else
+ {
+ psz_parser++;
+ }
+ }
+#if defined( WIN32 ) || defined( UNDER_CE )
+ if( psz_parser - psz_dup == 1 )
+ {
+ msg_Warn( p_sout, "drive letter %c: found in source string",
+ *psz_dup ) ;
+ psz_parser = "";
+ }
+#endif
+
+ if( !*psz_parser )
+ {
+ psz_access = psz_way = "";
+ psz_name = psz_dup;
+ }
+ else
+ {
+ *psz_parser++ = '\0';
+
+ /* let's skip '//' */
+ if( psz_parser[0] == '/' && psz_parser[1] == '/' )
+ {
+ psz_parser += 2 ;
+ }
+
+ psz_name = psz_parser ;
+
+ /* Come back to parse the access and mux plug-ins */
+ psz_parser = psz_dup;
+
+ if( !*psz_parser )
+ {
+ /* No access */
+ psz_access = "";
+ }
+ else if( *psz_parser == '/' )
+ {
+ /* No access */
+ psz_access = "";
+ psz_parser++;
+ }
+ else
+ {
+ psz_access = psz_parser;
+
+ while( *psz_parser && *psz_parser != '/' )
+ {
+ if( *psz_parser == '{' )
+ {
+ while( *psz_parser && *psz_parser != '}' )
+ {
+ psz_parser++;
+ }
+ if( *psz_parser )
+ {
+ psz_parser++;
+ }
+ }
+ else
+ {
+ psz_parser++;
+ }
+ }
+
+ if( *psz_parser == '/' )
+ {
+ *psz_parser++ = '\0';
+ }
+ }
+
+ if( !*psz_parser )
+ {
+ /* No mux */
+ psz_way = "";
+ }
+ else
+ {
+ psz_way = psz_parser;
+ }
+ }
+
+#if 0
+ if( ( psz_parser = strchr( psz_access, '{' ) ) != NULL )
+ {
+ mrl_ParseOptions( &p_mrl->p_access_options, psz_parser );
+ *psz_parser = '\0';
+ }
+
+ if( ( psz_parser = strchr( psz_way, '{' ) ) != NULL )
+ {
+ mrl_ParseOptions( &p_mrl->p_way_options, psz_parser );
+ *psz_parser = '\0';
+ }
+#endif
+
+ p_mrl->p_access_options = NULL;
+ p_mrl->p_way_options = NULL;
+
+ p_mrl->psz_access = strdup( psz_access );
+ p_mrl->psz_way = strdup( psz_way );
+ p_mrl->psz_name = strdup( psz_name );
+
+ return( VLC_SUCCESS );
+}
+
+
+/* mrl_Clean: clean p_mrl after a call to mrl_Parse */
+static void mrl_Clean( mrl_t *p_mrl )
+{
+ FREE( p_mrl->psz_access );
+ FREE( p_mrl->psz_way );
+ FREE( p_mrl->psz_name );
+}
+
+
+