Commit 949a4ce2 authored by Laurent Aimar's avatar Laurent Aimar

* all: reworked stream output. Now it handles mutliples outputs from

one input, just type --sout "<first url>#<second url>#..." (Yes it
is awfull, but I need suggestion).
   udp: correctly update sequence number in rtp.
parent 4befbe94
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* stream_output.h : stream output module * stream_output.h : stream output module
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Laurent Aimar <fenrir@via.ecp.fr> * Laurent Aimar <fenrir@via.ecp.fr>
...@@ -63,7 +63,6 @@ struct sout_packet_format_t ...@@ -63,7 +63,6 @@ struct sout_packet_format_t
vlc_fourcc_t i_fourcc; vlc_fourcc_t i_fourcc;
void *p_format; // WAVEFORMATEX or BITMAPINFOHEADER void *p_format; // WAVEFORMATEX or BITMAPINFOHEADER
}; };
struct sout_fifo_t struct sout_fifo_t
...@@ -76,23 +75,39 @@ struct sout_fifo_t ...@@ -76,23 +75,39 @@ struct sout_fifo_t
sout_buffer_t **pp_last; sout_buffer_t **pp_last;
}; };
/* for mux */
struct sout_input_t struct sout_input_t
{ {
vlc_mutex_t lock; // vlc_mutex_t lock;
sout_instance_t *p_sout; sout_instance_t *p_sout;
sout_packet_format_t input_format; sout_packet_format_t input_format;
sout_fifo_t *p_fifo; 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_NONE 0x00
#define SOUT_METHOD_FILE 0x10 #define SOUT_METHOD_FILE 0x10
#define SOUT_METHOD_NETWORK 0x20 #define SOUT_METHOD_NETWORK 0x20
struct sout_access_out_t struct sout_access_out_t
{ {
VLC_COMMON_MEMBERS VLC_COMMON_MEMBERS
...@@ -123,38 +138,72 @@ struct sout_access_out_t ...@@ -123,38 +138,72 @@ struct sout_access_out_t
#define SOUT_MUX_CAP_ERR_UNKNOWN 0x01 #define SOUT_MUX_CAP_ERR_UNKNOWN 0x01
#define SOUT_MUX_CAP_ERR_UNIMPLEMENTED 0x02 #define SOUT_MUX_CAP_ERR_UNIMPLEMENTED 0x02
typedef struct sout_instance_sys_t sout_instance_sys_t; typedef struct sout_mux_sys_t sout_mux_sys_t;
struct sout_instance_t struct sout_mux_t
{ {
VLC_COMMON_MEMBERS VLC_COMMON_MEMBERS
module_t *p_module;
sout_instance_t *p_sout;
char * psz_dest; char *psz_mux;
char * psz_access;
char * psz_mux;
char * psz_name;
int i_method;
sout_access_out_t *p_access; sout_access_out_t *p_access;
module_t *p_mux; int i_preheader;
void *p_mux_data; int (* pf_capacity) ( sout_mux_t *,
int i_mux_preheader;
int (* pf_mux_capacity) ( sout_instance_t *,
int, void *, void *); int, void *, void *);
int (* pf_mux_addstream )( sout_instance_t *, int (* pf_addstream )( sout_mux_t *,
sout_input_t * ); sout_input_t * );
int (* pf_mux_delstream )( sout_instance_t *, int (* pf_delstream )( sout_mux_t *,
sout_input_t * ); sout_input_t * );
int (* pf_mux ) ( sout_instance_t * ); int (* pf_mux ) ( sout_mux_t * );
vlc_mutex_t lock; /* here are all inputs accepted by muxer */
int i_nb_inputs; int i_nb_inputs;
sout_input_t **pp_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; sout_instance_sys_t *p_sys;
}; };
...@@ -178,9 +227,9 @@ VLC_EXPORT( sout_buffer_t *, sout_FifoShow, ( sout_fifo_t * ) ); ...@@ -178,9 +227,9 @@ VLC_EXPORT( sout_buffer_t *, sout_FifoShow, ( sout_fifo_t * ) );
#define sout_InputNew( a, b ) __sout_InputNew( VLC_OBJECT(a), b ) #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( sout_packetizer_input_t *, __sout_InputNew, ( vlc_object_t *, sout_packet_format_t * ) );
VLC_EXPORT( int, sout_InputDelete, ( sout_input_t * ) ); VLC_EXPORT( int, sout_InputDelete, ( sout_packetizer_input_t * ) );
VLC_EXPORT( int, sout_InputSendBuffer, ( sout_input_t *, sout_buffer_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( sout_buffer_t*, sout_BufferNew, ( sout_instance_t *, size_t ) );
VLC_EXPORT( int, sout_BufferRealloc,( sout_instance_t *, sout_buffer_t*, size_t ) ); VLC_EXPORT( int, sout_BufferRealloc,( sout_instance_t *, sout_buffer_t*, size_t ) );
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Collection of useful common types and macros definitions * Collection of useful common types and macros definitions
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN * 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> * Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr> * Vincent Seguin <seguin@via.ecp.fr>
...@@ -247,9 +247,11 @@ typedef struct subpicture_sys_t subpicture_sys_t; ...@@ -247,9 +247,11 @@ typedef struct subpicture_sys_t subpicture_sys_t;
typedef struct sout_instance_t sout_instance_t; typedef struct sout_instance_t sout_instance_t;
typedef struct sout_fifo_t sout_fifo_t; typedef struct sout_fifo_t sout_fifo_t;
typedef struct sout_input_t sout_input_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_buffer_t sout_buffer_t;
typedef struct sout_packet_format_t sout_packet_format_t; typedef struct sout_packet_format_t sout_packet_format_t;
typedef struct sout_access_out_t sout_access_out_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; typedef struct sout_access_out_sys_t sout_access_out_sys_t;
/* Decoders */ /* Decoders */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* udp.c * udp.c
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org> * Eric Petit <titer@videolan.org>
...@@ -125,18 +125,11 @@ static int Open( vlc_object_t *p_this ) ...@@ -125,18 +125,11 @@ static int Open( vlc_object_t *p_this )
return( VLC_EGENERIC ); return( VLC_EGENERIC );
} }
if( p_access->psz_access != NULL && if( p_access->psz_access != NULL &&
!strcmp( p_access->psz_access, "rtp" ) ) !strcmp( p_access->psz_access, "rtp" ) )
{ {
if( p_access->p_sout->psz_mux != NULL && msg_Warn( p_access, "becarefull that rtp ouput work only with ts payload(not an error)" );
*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 );
}
p_sys->b_rtpts = 1; p_sys->b_rtpts = 1;
} }
else else
...@@ -203,9 +196,10 @@ static int Open( vlc_object_t *p_this ) ...@@ -203,9 +196,10 @@ static int Open( vlc_object_t *p_this )
return( VLC_EGENERIC ); return( VLC_EGENERIC );
} }
srand( (uint32_t)mdate());
p_sys->p_buffer = NULL; p_sys->p_buffer = NULL;
p_sys->i_sequence_number = 12; // FIXME should be random, used by rtp p_sys->i_sequence_number = rand()&0xffff;
p_sys->i_ssrc = 4212; // FIXME " " " " " " p_sys->i_ssrc = rand()&0xffffffff;
p_access->pf_write = Write; p_access->pf_write = Write;
p_access->pf_seek = Seek; p_access->pf_seek = Seek;
...@@ -300,10 +294,12 @@ static int Write( sout_access_out_t *p_access, sout_buffer_t *p_buffer ) ...@@ -300,10 +294,12 @@ static int Write( sout_access_out_t *p_access, sout_buffer_t *p_buffer )
/* add rtp/ts header */ /* add rtp/ts header */
p_sys->p_buffer->p_buffer[0] = 0x80; p_sys->p_buffer->p_buffer[0] = 0x80;
p_sys->p_buffer->p_buffer[1] = 0x21; // mpeg2-ts p_sys->p_buffer->p_buffer[1] = 0x21; // mpeg2-ts
p_sys->p_buffer->p_buffer[2] = p_sys->p_buffer->p_buffer[2] =
( p_sys->i_sequence_number >> 8 )&0xff; ( p_sys->i_sequence_number >> 8 )&0xff;
p_sys->p_buffer->p_buffer[3] = p_sys->p_buffer->p_buffer[3] =
p_sys->i_sequence_number&0xff; 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[4] = ( i_timestamp >> 24 )&0xff;
p_sys->p_buffer->p_buffer[5] = ( i_timestamp >> 16 )&0xff; p_sys->p_buffer->p_buffer[5] = ( i_timestamp >> 16 )&0xff;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* avi.c * avi.c
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -63,13 +63,13 @@ ...@@ -63,13 +63,13 @@
static int Open ( vlc_object_t * ); static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * ); static void Close ( vlc_object_t * );
static int Capability(sout_instance_t *, int , void *, void * ); static int Capability(sout_mux_t *, int , void *, void * );
static int AddStream( sout_instance_t *, sout_input_t * ); static int AddStream( sout_mux_t *, sout_input_t * );
static int DelStream( sout_instance_t *, sout_input_t * ); static int DelStream( sout_mux_t *, sout_input_t * );
static int Mux ( sout_instance_t * ); static int Mux ( sout_mux_t * );
static sout_buffer_t *avi_HeaderCreateRIFF( sout_instance_t *p_sout ); static sout_buffer_t *avi_HeaderCreateRIFF( sout_mux_t * );
static sout_buffer_t *avi_HeaderCreateidx1( sout_instance_t *p_sout ); static sout_buffer_t *avi_HeaderCreateidx1( sout_mux_t * );
static void SetFCC( uint8_t *p, char *fcc ) static void SetFCC( uint8_t *p, char *fcc )
{ {
...@@ -136,7 +136,7 @@ typedef struct avi_idx1_s ...@@ -136,7 +136,7 @@ typedef struct avi_idx1_s
avi_idx1_entry_t *entry; avi_idx1_entry_t *entry;
} avi_idx1_t; } avi_idx1_t;
typedef struct sout_mux_s struct sout_mux_sys_t
{ {
int i_streams; int i_streams;
int i_stream_video; int i_stream_video;
...@@ -147,39 +147,39 @@ typedef struct sout_mux_s ...@@ -147,39 +147,39 @@ typedef struct sout_mux_s
avi_idx1_t idx1; avi_idx1_t idx1;
off_t i_idx1_size; off_t i_idx1_size;
} sout_mux_t; };
/***************************************************************************** /*****************************************************************************
* Open: * Open:
*****************************************************************************/ *****************************************************************************/
static int Open( vlc_object_t *p_this ) 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;
sout_mux_t *p_mux; sout_mux_sys_t *p_sys = p_mux->p_sys;
sout_buffer_t *p_hdr; sout_buffer_t *p_hdr;
p_mux = malloc( sizeof( sout_mux_t ) ); p_sys = malloc( sizeof( sout_mux_sys_t ) );
p_mux->i_streams = 0; p_sys->i_streams = 0;
p_mux->i_stream_video = -1; p_sys->i_stream_video = -1;
p_mux->i_movi_size = 0; p_sys->i_movi_size = 0;
p_mux->idx1.i_entry_count = 0; p_sys->idx1.i_entry_count = 0;
p_mux->idx1.i_entry_max = 10000; p_sys->idx1.i_entry_max = 10000;
p_mux->idx1.entry = calloc( p_mux->idx1.i_entry_max, sizeof( avi_idx1_entry_t ) ); 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_mux->pf_capacity = Capability;
p_sout->pf_mux_addstream = AddStream; p_mux->pf_addstream = AddStream;
p_sout->pf_mux_delstream = DelStream; p_mux->pf_delstream = DelStream;
p_sout->pf_mux = Mux; p_mux->pf_mux = Mux;
p_sout->p_mux_data = (void*)p_mux; p_mux->p_sys = p_sys;
p_sout->i_mux_preheader = 8; // (fourcc,length) header p_mux->i_preheader = 8; // (fourcc,length) header
/* room to add header at the end */ /* 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 ); 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; return VLC_SUCCESS;
} }
...@@ -190,24 +190,25 @@ static int Open( vlc_object_t *p_this ) ...@@ -190,24 +190,25 @@ static int Open( vlc_object_t *p_this )
static void Close( vlc_object_t * p_this ) 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_this;
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, *p_idx1; sout_buffer_t *p_hdr, *p_idx1;
int i_stream; int i_stream;
msg_Info( p_sout, "Close" ); msg_Info( p_mux, "Close" );
/* first create idx1 chunk (write at the end of the stream */ /* first create idx1 chunk (write at the end of the stream */
p_idx1 = avi_HeaderCreateidx1( p_sout ); p_idx1 = avi_HeaderCreateidx1( p_mux );
p_mux->i_idx1_size = p_idx1->i_size; p_sys->i_idx1_size = p_idx1->i_size;
sout_AccessOutWrite( p_sout->p_access, p_idx1 ); sout_AccessOutWrite( p_mux->p_access, p_idx1 );
/* calculate some value for headers creations */ /* 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; avi_stream_t *p_stream;
p_stream = &p_mux->stream[i_stream]; p_stream = &p_sys->stream[i_stream];
p_stream->f_fps = 25; p_stream->f_fps = 25;
if( p_stream->i_duration > 0 ) if( p_stream->i_duration > 0 )
...@@ -224,19 +225,19 @@ static void Close( vlc_object_t * p_this ) ...@@ -224,19 +225,19 @@ static void Close( vlc_object_t * p_this )
(uint64_t)p_stream->i_totalsize / (uint64_t)p_stream->i_totalsize /
(uint64_t)p_stream->i_duration; (uint64_t)p_stream->i_duration;
} }
msg_Err( p_sout,"stream[%d] duration:%lld totalsize:%lld frames:%d fps:%f kb/s:%d", msg_Err( p_mux, "stream[%d] duration:%lld totalsize:%lld frames:%d fps:%f kb/s:%d",
i_stream, i_stream,
p_stream->i_duration/1000000, p_stream->i_totalsize, p_stream->i_duration/1000000, p_stream->i_totalsize,
p_stream->i_frames, p_stream->i_frames,
p_stream->f_fps, p_stream->i_bitrate/1024 ); p_stream->f_fps, p_stream->i_bitrate/1024 );
} }
p_hdr = avi_HeaderCreateRIFF( p_sout ); p_hdr = avi_HeaderCreateRIFF( p_mux );
sout_AccessOutSeek( p_sout->p_access, 0 ); sout_AccessOutSeek( p_mux->p_access, 0 );
sout_AccessOutWrite( p_sout->p_access, p_hdr ); 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 ) switch( i_query )
{ {
...@@ -248,27 +249,27 @@ static int Capability( sout_instance_t *p_sout, int i_query, void *p_args, void ...@@ -248,27 +249,27 @@ static int Capability( sout_instance_t *p_sout, int i_query, void *p_args, void
} }
} }
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;
avi_stream_t *p_stream; 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 ); return( -1 );
} }
if( p_input->input_format.p_format == NULL ) if( p_input->input_format.p_format == NULL )
{ {
msg_Err( p_sout, "stream descriptor missing" ); msg_Err( p_mux, "stream descriptor missing" );
return( -1 ); return( -1 );
} }
msg_Dbg( p_sout, "adding input" ); msg_Dbg( p_mux, "adding input" );
p_input->p_mux_data = malloc( sizeof( int ) ); p_input->p_sys = malloc( sizeof( int ) );
*((int*)p_input->p_mux_data) = p_mux->i_streams; *((int*)p_input->p_sys) = p_sys->i_streams;
p_stream = &p_mux->stream[p_mux->i_streams]; p_stream = &p_sys->stream[p_sys->i_streams];
switch( p_input->input_format.i_cat ) switch( p_input->input_format.i_cat )
{ {
...@@ -278,8 +279,8 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input ) ...@@ -278,8 +279,8 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
(WAVEFORMATEX*)p_input->input_format.p_format; (WAVEFORMATEX*)p_input->input_format.p_format;
p_stream->i_cat = AUDIO_ES; p_stream->i_cat = AUDIO_ES;
p_stream->fcc[0] = '0' + p_mux->i_streams / 10; p_stream->fcc[0] = '0' + p_sys->i_streams / 10;
p_stream->fcc[1] = '0' + p_mux->i_streams % 10; p_stream->fcc[1] = '0' + p_sys->i_streams % 10;
p_stream->fcc[2] = 'w'; p_stream->fcc[2] = 'w';
p_stream->fcc[3] = 'b'; p_stream->fcc[3] = 'b';
...@@ -296,13 +297,13 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input ) ...@@ -296,13 +297,13 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
(BITMAPINFOHEADER*)p_input->input_format.p_format;; (BITMAPINFOHEADER*)p_input->input_format.p_format;;
p_stream->i_cat = VIDEO_ES; p_stream->i_cat = VIDEO_ES;
p_stream->fcc[0] = '0' + p_mux->i_streams / 10; p_stream->fcc[0] = '0' + p_sys->i_streams / 10;
p_stream->fcc[1] = '0' + p_mux->i_streams % 10; p_stream->fcc[1] = '0' + p_sys->i_streams % 10;
p_stream->fcc[2] = 'd'; p_stream->fcc[2] = 'd';
p_stream->fcc[3] = 'c'; 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_wf = NULL;
p_stream->p_bih = malloc( p_bih->biSize ); p_stream->p_bih = malloc( p_bih->biSize );
...@@ -318,37 +319,36 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input ) ...@@ -318,37 +319,36 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
p_stream->i_frames = 0; p_stream->i_frames = 0;
p_stream->i_duration = 0; p_stream->i_duration = 0;
p_mux->i_streams++; p_sys->i_streams++;
return( 0 ); 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 ); 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; sout_mux_sys_t *p_sys = p_mux->p_sys;
avi_stream_t *p_stream; avi_stream_t *p_stream;
int i_stream; int i_stream;
int i; 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; int i_count;
sout_fifo_t *p_fifo; sout_fifo_t *p_fifo;
i_stream = *((int*)p_sout->pp_inputs[i]->p_mux_data ); i_stream = *((int*)p_mux->pp_inputs[i]->p_sys );
p_stream = &p_mux->stream[i_stream]; 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; i_count = p_fifo->i_depth;
while( i_count > 0 ) while( i_count > 0 )
{ {
...@@ -362,31 +362,31 @@ static int Mux ( sout_instance_t *p_sout ) ...@@ -362,31 +362,31 @@ static int Mux ( sout_instance_t *p_sout )
p_stream->i_totalsize += p_data->i_size; p_stream->i_totalsize += p_data->i_size;
/* add idx1 entry for this frame */ /* 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 ); memcpy( p_idx->fcc, p_stream->fcc, 4 );
p_idx->i_flags = AVIIF_KEYFRAME; 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_idx->i_length= p_data->i_size;
p_mux->idx1.i_entry_count++; p_sys->idx1.i_entry_count++;
if( p_mux->idx1.i_entry_count >= p_mux->idx1.i_entry_max ) if( p_sys->idx1.i_entry_count >= p_sys->idx1.i_entry_max )
{ {
p_mux->idx1.i_entry_max += 10000; p_sys->idx1.i_entry_max += 10000;
p_mux->idx1.entry = realloc( p_mux->idx1.entry, p_sys->idx1.entry = realloc( p_sys->idx1.entry,
p_mux->idx1.i_entry_max * sizeof( avi_idx1_entry_t ) ); 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 */ /* there isn't enough data in preheader */
sout_buffer_t *p_hdr; 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 ); SetFCC( p_hdr->p_buffer, p_stream->fcc );
SetDWLE( p_hdr->p_buffer + 4, p_data->i_size ); SetDWLE( p_hdr->p_buffer + 4, p_data->i_size );
sout_AccessOutWrite( p_sout->p_access, p_hdr ); sout_AccessOutWrite( p_mux->p_access, p_hdr );
p_mux->i_movi_size += p_hdr->i_size; p_sys->i_movi_size += p_hdr->i_size;
} }
else else
...@@ -397,12 +397,12 @@ static int Mux ( sout_instance_t *p_sout ) ...@@ -397,12 +397,12 @@ static int Mux ( sout_instance_t *p_sout )
if( p_data->i_size & 0x01 ) 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; p_data->i_size += 1;
} }
sout_AccessOutWrite( p_sout->p_access, p_data ); sout_AccessOutWrite( p_mux->p_access, p_data );
p_mux->i_movi_size += p_data->i_size; p_sys->i_movi_size += p_data->i_size;
i_count--; i_count--;
} }
...@@ -511,10 +511,10 @@ static void bo_AddMem( buffer_out_t *p_bo, int i_size, uint8_t *p_mem ) ...@@ -511,10 +511,10 @@ static void bo_AddMem( buffer_out_t *p_bo, int i_size, uint8_t *p_mem )
bo_AddDWordLE( &_bo_sav_, p_bo->i_buffer - _bo_sav_.i_buffer - 4 ); \ bo_AddDWordLE( &_bo_sav_, p_bo->i_buffer - _bo_sav_.i_buffer - 4 ); \
return( i_err ); 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 ) buffer_out_t *p_bo )
{ {
sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data; sout_mux_sys_t *p_sys = p_mux->p_sys;
avi_stream_t *p_video = NULL; avi_stream_t *p_video = NULL;
int i_stream; int i_stream;
uint32_t i_microsecperframe; uint32_t i_microsecperframe;
...@@ -522,9 +522,9 @@ static int avi_HeaderAdd_avih( sout_instance_t *p_sout, ...@@ -522,9 +522,9 @@ static int avi_HeaderAdd_avih( sout_instance_t *p_sout,
int i_totalframes; int i_totalframes;
AVI_BOX_ENTER( "avih" ); 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 ) if( p_video->i_frames <= 0 )
{ {
p_video = NULL; p_video = NULL;
...@@ -535,23 +535,23 @@ static int avi_HeaderAdd_avih( sout_instance_t *p_sout, ...@@ -535,23 +535,23 @@ static int avi_HeaderAdd_avih( sout_instance_t *p_sout,
{ {
i_microsecperframe = i_microsecperframe =
(uint32_t)( (float)1000000 / (uint32_t)( (float)1000000 /
(float)p_mux->stream[p_mux->i_stream_video].f_fps ); (float)p_sys->stream[p_sys->i_stream_video].f_fps );
i_totalframes = p_mux->stream[p_mux->i_stream_video].i_frames; i_totalframes = p_sys->stream[p_sys->i_stream_video].i_frames;
} }
else 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_microsecperframe = 0;
i_totalframes = 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 += i_maxbytespersec +=
p_mux->stream[p_mux->i_stream_video].i_totalsize / p_sys->stream[p_sys->i_stream_video].i_totalsize /
p_mux->stream[p_mux->i_stream_video].i_duration; p_sys->stream[p_sys->i_stream_video].i_duration;
} }
} }
...@@ -563,7 +563,7 @@ static int avi_HeaderAdd_avih( sout_instance_t *p_sout, ...@@ -563,7 +563,7 @@ static int avi_HeaderAdd_avih( sout_instance_t *p_sout,
AVIF_ISINTERLEAVED ); /* flags */ AVIF_ISINTERLEAVED ); /* flags */
bo_AddDWordLE( p_bo, i_totalframes ); bo_AddDWordLE( p_bo, i_totalframes );
bo_AddDWordLE( p_bo, 0 ); /* initial frame */ 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 */ bo_AddDWordLE( p_bo, 1024 * 1024 ); /* suggested buffer size */
if( p_video ) if( p_video )
{ {
...@@ -582,11 +582,10 @@ static int avi_HeaderAdd_avih( sout_instance_t *p_sout, ...@@ -582,11 +582,10 @@ static int avi_HeaderAdd_avih( sout_instance_t *p_sout,
AVI_BOX_EXIT( 0 ); 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, buffer_out_t *p_bo,
avi_stream_t *p_stream ) avi_stream_t *p_stream )
{ {
// sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
AVI_BOX_ENTER( "strh" ); AVI_BOX_ENTER( "strh" );
switch( p_stream->i_cat ) switch( p_stream->i_cat )
...@@ -652,11 +651,10 @@ static int avi_HeaderAdd_strh( sout_instance_t *p_sout, ...@@ -652,11 +651,10 @@ static int avi_HeaderAdd_strh( sout_instance_t *p_sout,
AVI_BOX_EXIT( 0 ); 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, buffer_out_t *p_bo,
avi_stream_t *p_stream ) avi_stream_t *p_stream )
{ {
// sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
AVI_BOX_ENTER( "strf" ); AVI_BOX_ENTER( "strf" );
switch( p_stream->i_cat ) switch( p_stream->i_cat )
...@@ -699,45 +697,44 @@ static int avi_HeaderAdd_strf( sout_instance_t *p_sout, ...@@ -699,45 +697,44 @@ static int avi_HeaderAdd_strf( sout_instance_t *p_sout,
AVI_BOX_EXIT( 0 ); 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, buffer_out_t *p_bo,
avi_stream_t *p_stream ) avi_stream_t *p_stream )
{ {
// sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data;
AVI_BOX_ENTER_LIST( "strl" ); AVI_BOX_ENTER_LIST( "strl" );
avi_HeaderAdd_strh( p_sout, p_bo, p_stream ); avi_HeaderAdd_strh( p_mux, p_bo, p_stream );
avi_HeaderAdd_strf( p_sout, p_bo, p_stream ); avi_HeaderAdd_strf( p_mux, p_bo, p_stream );
AVI_BOX_EXIT( 0 ); 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; sout_buffer_t *p_hdr;
int i_stream; int i_stream;
int i_maxbytespersec; int i_maxbytespersec;
int i_junk; int i_junk;
buffer_out_t bo; 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 ); memset( p_hdr->p_buffer, 0, HDR_SIZE );
bo_Init( &bo, HDR_SIZE, p_hdr->p_buffer ); bo_Init( &bo, HDR_SIZE, p_hdr->p_buffer );
bo_AddFCC( &bo, "RIFF" ); 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, "AVI " );
bo_AddFCC( &bo, "LIST" ); bo_AddFCC( &bo, "LIST" );
bo_AddDWordLE( &bo, HDR_SIZE - 8); bo_AddDWordLE( &bo, HDR_SIZE - 8);
bo_AddFCC( &bo, "hdrl" ); bo_AddFCC( &bo, "hdrl" );
avi_HeaderAdd_avih( p_sout, &bo ); avi_HeaderAdd_avih( p_mux, &bo );
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++ )
{ {
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; i_junk = HDR_SIZE - bo.i_buffer - 8 - 12;
...@@ -746,35 +743,35 @@ static sout_buffer_t *avi_HeaderCreateRIFF( sout_instance_t *p_sout ) ...@@ -746,35 +743,35 @@ static sout_buffer_t *avi_HeaderCreateRIFF( sout_instance_t *p_sout )
bo.i_buffer += i_junk; bo.i_buffer += i_junk;
bo_AddFCC( &bo, "LIST" ); 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" ); bo_AddFCC( &bo, "movi" );
return( p_hdr ); 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; sout_buffer_t *p_idx1;
uint32_t i_idx1_size; uint32_t i_idx1_size;
unsigned int i; unsigned int i;
buffer_out_t bo; 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 ); memset( p_idx1->p_buffer, 0, i_idx1_size );
bo_Init( &bo, i_idx1_size, p_idx1->p_buffer ); bo_Init( &bo, i_idx1_size, p_idx1->p_buffer );
bo_AddFCC( &bo, "idx1" ); bo_AddFCC( &bo, "idx1" );
bo_AddDWordLE( &bo, i_idx1_size ); 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_AddFCC( &bo, p_sys->idx1.entry[i].fcc );
bo_AddDWordLE( &bo, p_mux->idx1.entry[i].i_flags ); bo_AddDWordLE( &bo, p_sys->idx1.entry[i].i_flags );
bo_AddDWordLE( &bo, p_mux->idx1.entry[i].i_pos ); bo_AddDWordLE( &bo, p_sys->idx1.entry[i].i_pos );
bo_AddDWordLE( &bo, p_mux->idx1.entry[i].i_length ); bo_AddDWordLE( &bo, p_sys->idx1.entry[i].i_length );
} }
return( p_idx1 ); return( p_idx1 );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dummy.c * dummy.c
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org> * Eric Petit <titer@videolan.org>
...@@ -48,10 +48,10 @@ ...@@ -48,10 +48,10 @@
static int Open ( vlc_object_t * ); static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * ); static void Close ( vlc_object_t * );
static int Capability(sout_instance_t *, int, void *, void * ); static int Capability(sout_mux_t *, int, void *, void * );
static int AddStream( sout_instance_t *, sout_input_t * ); static int AddStream( sout_mux_t *, sout_input_t * );
static int DelStream( sout_instance_t *, sout_input_t * ); static int DelStream( sout_mux_t *, sout_input_t * );
static int Mux ( sout_instance_t * ); static int Mux ( sout_mux_t * );
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
...@@ -60,6 +60,7 @@ vlc_module_begin(); ...@@ -60,6 +60,7 @@ vlc_module_begin();
set_description( _("Dummy muxer") ); set_description( _("Dummy muxer") );
set_capability( "sout mux", 5 ); set_capability( "sout mux", 5 );
add_shortcut( "dummy" ); add_shortcut( "dummy" );
add_shortcut( "es" );
set_callbacks( Open, Close ); set_callbacks( Open, Close );
vlc_module_end(); vlc_module_end();
...@@ -68,14 +69,14 @@ vlc_module_end(); ...@@ -68,14 +69,14 @@ vlc_module_end();
*****************************************************************************/ *****************************************************************************/
static int Open( vlc_object_t *p_this ) 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_mux->pf_capacity = Capability;
p_sout->pf_mux_addstream = AddStream; p_mux->pf_addstream = AddStream;
p_sout->pf_mux_delstream = DelStream; p_mux->pf_delstream = DelStream;
p_sout->pf_mux = Mux; p_mux->pf_mux = Mux;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -86,11 +87,12 @@ static int Open( vlc_object_t *p_this ) ...@@ -86,11 +87,12 @@ static int Open( vlc_object_t *p_this )
static void Close( vlc_object_t * p_this ) 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_this;
msg_Info( p_sout, "Close" );
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 ) switch( i_query )
{ {
...@@ -102,28 +104,28 @@ static int Capability( sout_instance_t *p_sout, int i_query, void *p_args, void ...@@ -102,28 +104,28 @@ static int Capability( sout_instance_t *p_sout, int i_query, void *p_args, void
} }
} }
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 ); 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 ); return( 0 );
} }
static int Mux ( sout_instance_t *p_sout ) static int Mux ( sout_mux_t *p_mux )
{ {
int i; 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; int i_count;
sout_fifo_t *p_fifo; 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; i_count = p_fifo->i_depth;
while( i_count > 0 ) while( i_count > 0 )
{ {
...@@ -131,7 +133,7 @@ static int Mux ( sout_instance_t *p_sout ) ...@@ -131,7 +133,7 @@ static int Mux ( sout_instance_t *p_sout )
p_data = sout_FifoGet( p_fifo ); p_data = sout_FifoGet( p_fifo );
sout_AccessOutWrite( p_sout->p_access, p_data ); sout_AccessOutWrite( p_mux->p_access, p_data );
i_count--; i_count--;
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ps.c * ps.c
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org> * Eric Petit <titer@videolan.org>
...@@ -51,10 +51,10 @@ ...@@ -51,10 +51,10 @@
static int Open ( vlc_object_t * ); static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * ); static void Close ( vlc_object_t * );
static int Capability(sout_instance_t *, int, void *, void * ); static int Capability(sout_mux_t *, int, void *, void * );
static int AddStream( sout_instance_t *, sout_input_t * ); static int AddStream( sout_mux_t *, sout_input_t * );
static int DelStream( sout_instance_t *, sout_input_t * ); static int DelStream( sout_mux_t *, sout_input_t * );
static int Mux ( sout_instance_t * ); static int Mux ( sout_mux_t * );
static void SetWBE ( uint8_t *p, uint16_t v ) static void SetWBE ( uint8_t *p, uint16_t v )
{ {
...@@ -88,7 +88,7 @@ typedef struct ps_stream_s ...@@ -88,7 +88,7 @@ typedef struct ps_stream_s
} ps_stream_t; } ps_stream_t;
typedef struct sout_mux_s struct sout_mux_sys_t
{ {
int i_stream_id_mpga; int i_stream_id_mpga;
...@@ -101,34 +101,34 @@ typedef struct sout_mux_s ...@@ -101,34 +101,34 @@ typedef struct sout_mux_s
int i_pes_count; int i_pes_count;
int i_system_header; int i_system_header;
} sout_mux_t; };
/***************************************************************************** /*****************************************************************************
* Open: * Open:
*****************************************************************************/ *****************************************************************************/
static int Open( vlc_object_t *p_this ) 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;
sout_mux_t *p_mux; 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_mux->pf_capacity = Capability;
p_sout->pf_mux_addstream = AddStream; p_mux->pf_addstream = AddStream;
p_sout->pf_mux_delstream = DelStream; p_mux->pf_delstream = DelStream;
p_sout->pf_mux = Mux; p_mux->pf_mux = Mux;
p_sout->p_mux_data = (void*)p_mux; p_mux->p_sys = p_sys;
p_sout->i_mux_preheader = 30; // really enough for a pes header p_mux->i_preheader = 30; // really enough for a pes header
p_mux->i_stream_id_mpga = 0xc0; p_sys->i_stream_id_mpga = 0xc0;
p_mux->i_stream_id_a52 = 0x80; p_sys->i_stream_id_a52 = 0x80;
p_mux->i_stream_id_mpgv = 0xe0; p_sys->i_stream_id_mpgv = 0xe0;
p_mux->i_audio_bound = 0; p_sys->i_audio_bound = 0;
p_mux->i_video_bound = 0; p_sys->i_video_bound = 0;
p_mux->i_system_header = 0; p_sys->i_system_header = 0;
p_mux->i_pes_count = 0; p_sys->i_pes_count = 0;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -139,23 +139,22 @@ static int Open( vlc_object_t *p_this ) ...@@ -139,23 +139,22 @@ static int Open( vlc_object_t *p_this )
static void Close( vlc_object_t * p_this ) 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_this;
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_end; 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 ); SetDWBE( p_end->p_buffer, 0x01b9 );
sout_AccessOutWrite( p_sout->p_access, p_end ); sout_AccessOutWrite( p_mux->p_access, p_end );
free( p_mux );
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 ) switch( i_query )
{ {
...@@ -167,13 +166,13 @@ static int Capability( sout_instance_t *p_sout, int i_query, void *p_args, void ...@@ -167,13 +166,13 @@ static int Capability( sout_instance_t *p_sout, int i_query, void *p_args, void
} }
} }
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; ps_stream_t *p_stream;
msg_Dbg( p_sout, "adding input" ); msg_Dbg( p_mux, "adding input" );
p_input->p_mux_data = (void*)p_stream = malloc( sizeof( ps_stream_t ) ); p_input->p_sys = (void*)p_stream = malloc( sizeof( ps_stream_t ) );
p_stream->i_ok = 0; p_stream->i_ok = 0;
switch( p_input->input_format.i_cat ) switch( p_input->input_format.i_cat )
{ {
...@@ -182,9 +181,9 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input ) ...@@ -182,9 +181,9 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
switch( p_input->input_format.i_fourcc ) switch( p_input->input_format.i_fourcc )
{ {
case VLC_FOURCC( 'm', 'p', 'g', 'v' ): case VLC_FOURCC( 'm', 'p', 'g', 'v' ):
p_stream->i_stream_id = p_mux->i_stream_id_mpgv; p_stream->i_stream_id = p_sys->i_stream_id_mpgv;
p_mux->i_stream_id_mpgv++; p_sys->i_stream_id_mpgv++;
p_mux->i_video_bound++; p_sys->i_video_bound++;
break; break;
default: default:
return( -1 ); return( -1 );
...@@ -195,14 +194,14 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input ) ...@@ -195,14 +194,14 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
{ {
case VLC_FOURCC( 'a', '5', '2', ' ' ): case VLC_FOURCC( 'a', '5', '2', ' ' ):
case VLC_FOURCC( 'a', '5', '2', 'b' ): case VLC_FOURCC( 'a', '5', '2', 'b' ):
p_stream->i_stream_id = p_mux->i_stream_id_a52 | ( 0xbd << 8 ); p_stream->i_stream_id = p_sys->i_stream_id_a52 | ( 0xbd << 8 );
p_mux->i_stream_id_a52++; p_sys->i_stream_id_a52++;
p_mux->i_audio_bound++; p_sys->i_audio_bound++;
break; break;
case VLC_FOURCC( 'm', 'p', 'g', 'a' ): case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
p_stream->i_stream_id = p_mux->i_stream_id_mpga; p_stream->i_stream_id = p_sys->i_stream_id_mpga;
p_mux->i_stream_id_mpga++; p_sys->i_stream_id_mpga++;
p_mux->i_audio_bound++; p_sys->i_audio_bound++;
break; break;
default: default:
return( -1 ); return( -1 );
...@@ -213,23 +212,23 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input ) ...@@ -213,23 +212,23 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
} }
p_stream->i_ok = 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 ); 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 ) if( p_stream )
{ {
free( 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 ) mtime_t i_dts )
{ {
sout_buffer_t *p_hdr; sout_buffer_t *p_hdr;
...@@ -238,7 +237,7 @@ static int MuxWritePackHeader( sout_instance_t *p_sout, ...@@ -238,7 +237,7 @@ static int MuxWritePackHeader( sout_instance_t *p_sout,
i_src = i_dts * 9 / 100; 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_initwrite( &bits, 14, p_hdr->p_buffer );
bits_write( &bits, 32, 0x01ba ); bits_write( &bits, 32, 0x01ba );
bits_write( &bits, 2, 0x01 ); // FIXME ?? bits_write( &bits, 2, 0x01 ); // FIXME ??
...@@ -258,18 +257,18 @@ static int MuxWritePackHeader( sout_instance_t *p_sout, ...@@ -258,18 +257,18 @@ static int MuxWritePackHeader( sout_instance_t *p_sout,
bits_write( &bits, 5, 0x1f ); // FIXME reserved bits_write( &bits, 5, 0x1f ); // FIXME reserved
bits_write( &bits, 3, 0 ); // stuffing bytes bits_write( &bits, 3, 0 ); // stuffing bytes
p_hdr->i_size = 14; p_hdr->i_size = 14;
sout_AccessOutWrite( p_sout->p_access, p_hdr ); sout_AccessOutWrite( p_mux->p_access, p_hdr );
return( 0 ); 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; sout_buffer_t *p_hdr;
bits_buffer_t bits; 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_initwrite( &bits, 12, p_hdr->p_buffer );
bits_write( &bits, 32, 0x01bb ); bits_write( &bits, 32, 0x01bb );
...@@ -278,7 +277,7 @@ static int MuxWriteSystemHeader( sout_instance_t *p_sout ) ...@@ -278,7 +277,7 @@ static int MuxWriteSystemHeader( sout_instance_t *p_sout )
bits_write( &bits, 22, 0 ); // FIXME rate bound bits_write( &bits, 22, 0 ); // FIXME rate bound
bits_write( &bits, 1, 1 ); 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 ); // fixed flag
bits_write( &bits, 1, 0 ); // CSPS flag bits_write( &bits, 1, 0 ); // CSPS flag
bits_write( &bits, 1, 0 ); // system audio lock flag bits_write( &bits, 1, 0 ); // system audio lock flag
...@@ -286,19 +285,19 @@ static int MuxWriteSystemHeader( sout_instance_t *p_sout ) ...@@ -286,19 +285,19 @@ static int MuxWriteSystemHeader( sout_instance_t *p_sout )
bits_write( &bits, 1, 1 ); // marker bit 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, 1, 0 ); // packet rate restriction flag
bits_write( &bits, 7, 0x7f ); // reserved bits bits_write( &bits, 7, 0x7f ); // reserved bits
/* FIXME missing stream_id ... */ /* FIXME missing stream_id ... */
sout_AccessOutWrite( p_sout->p_access, p_hdr ); sout_AccessOutWrite( p_mux->p_access, p_hdr );
return( 0 ); return( 0 );
} }
/* return stream number to be muxed */ /* 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, int *pi_stream,
mtime_t *pi_dts ) mtime_t *pi_dts )
{ {
...@@ -306,11 +305,11 @@ static int MuxGetStream( sout_instance_t *p_sout, ...@@ -306,11 +305,11 @@ static int MuxGetStream( sout_instance_t *p_sout,
int i_stream; int i_stream;
int i; 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; 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 ) if( p_fifo->i_depth > 1 )
{ {
...@@ -342,9 +341,9 @@ static int MuxGetStream( sout_instance_t *p_sout, ...@@ -342,9 +341,9 @@ static int MuxGetStream( sout_instance_t *p_sout,
} }
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;
mtime_t i_dts; mtime_t i_dts;
int i_stream; int i_stream;
...@@ -355,30 +354,30 @@ static int Mux ( sout_instance_t *p_sout ) ...@@ -355,30 +354,30 @@ static int Mux ( sout_instance_t *p_sout )
sout_fifo_t *p_fifo; sout_fifo_t *p_fifo;
sout_buffer_t *p_data; 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_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 ); // MuxWriteSystemHeader( p_sout );
} }
p_data = sout_FifoGet( p_fifo ); p_data = sout_FifoGet( p_fifo );
E_( EStoPES )( p_sout, &p_data, p_data, p_stream->i_stream_id, 1); E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1);
sout_AccessOutWrite( p_sout->p_access, p_data ); sout_AccessOutWrite( p_mux->p_access, p_data );
p_mux->i_pes_count++; p_sys->i_pes_count++;
} }
return( 0 ); return( 0 );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ts.c * ts.c
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org> * Eric Petit <titer@videolan.org>
...@@ -82,7 +82,7 @@ typedef struct ts_stream_s ...@@ -82,7 +82,7 @@ typedef struct ts_stream_s
uint8_t *p_decoder_specific_info; uint8_t *p_decoder_specific_info;
} ts_stream_t; } ts_stream_t;
typedef struct sout_mux_s struct sout_mux_sys_t
{ {
int i_pcr_pid; int i_pcr_pid;
int i_stream_id_mpga; int i_stream_id_mpga;
...@@ -104,7 +104,7 @@ typedef struct sout_mux_s ...@@ -104,7 +104,7 @@ typedef struct sout_mux_s
int i_mpeg4_streams; int i_mpeg4_streams;
} sout_mux_t; };
/***************************************************************************** /*****************************************************************************
...@@ -114,21 +114,21 @@ static int Open ( vlc_object_t * ); ...@@ -114,21 +114,21 @@ static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * ); static void Close ( vlc_object_t * );
static int Capability(sout_instance_t *, int, void *, void * ); static int Capability(sout_mux_t *, int, void *, void * );
static int AddStream( sout_instance_t *, sout_input_t * ); static int AddStream( sout_mux_t *, sout_input_t * );
static int DelStream( sout_instance_t *, sout_input_t * ); static int DelStream( sout_mux_t *, sout_input_t * );
static int Mux ( sout_instance_t * ); static int Mux ( sout_mux_t * );
/* Reserve a pid and return it */ /* 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 GetPAT( sout_mux_t *p_mux, sout_buffer_t **pp_ts );
static int GetPMT( sout_instance_t *p_sout, sout_buffer_t **pp_ts ); static int GetPMT( sout_mux_t *p_mux, sout_buffer_t **pp_ts );
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
...@@ -153,41 +153,41 @@ vlc_module_end(); ...@@ -153,41 +153,41 @@ vlc_module_end();
*****************************************************************************/ *****************************************************************************/
static int Open( vlc_object_t *p_this ) 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;
sout_mux_t *p_mux; 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_mux->pf_capacity = Capability;
p_sout->pf_mux_addstream = AddStream; p_mux->pf_addstream = AddStream;
p_sout->pf_mux_delstream = DelStream; p_mux->pf_delstream = DelStream;
p_sout->pf_mux = Mux; p_mux->pf_mux = Mux;
p_sout->p_mux_data = (void*)p_mux; p_mux->p_sys = p_sys;
p_sout->i_mux_preheader = 30; // really enough for a pes header p_mux->i_preheader = 30; // really enough for a pes header
srand( (uint32_t)mdate() ); srand( (uint32_t)mdate() );
p_mux->i_stream_id_mpga = 0xc0; p_sys->i_stream_id_mpga = 0xc0;
p_mux->i_stream_id_a52 = 0x80; p_sys->i_stream_id_a52 = 0x80;
p_mux->i_stream_id_mpgv = 0xe0; p_sys->i_stream_id_mpgv = 0xe0;
p_mux->i_audio_bound = 0; p_sys->i_audio_bound = 0;
p_mux->i_video_bound = 0; p_sys->i_video_bound = 0;
p_mux->i_pat_version_number = rand() % 32; p_sys->i_pat_version_number = rand() % 32;
p_mux->pat.i_pid = 0; p_sys->pat.i_pid = 0;
p_mux->pat.i_continuity_counter = 0; p_sys->pat.i_continuity_counter = 0;
p_mux->i_pmt_version_number = rand() % 32; p_sys->i_pmt_version_number = rand() % 32;
p_mux->pmt.i_pid = 0x10; p_sys->pmt.i_pid = 0x10;
p_mux->pmt.i_continuity_counter = 0; p_sys->pmt.i_continuity_counter = 0;
p_mux->i_pid_free = 0x11; p_sys->i_pid_free = 0x11;
p_mux->i_pcr_pid = 0x1fff; p_sys->i_pcr_pid = 0x1fff;
p_mux->i_mpeg4_streams = 0; p_sys->i_mpeg4_streams = 0;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -198,16 +198,16 @@ static int Open( vlc_object_t *p_this ) ...@@ -198,16 +198,16 @@ static int Open( vlc_object_t *p_this )
static void Close( vlc_object_t * p_this ) 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_this;
sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data; 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 );
p_sout->p_mux_data = NULL; 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 ) switch( i_query )
{ {
...@@ -219,20 +219,20 @@ static int Capability( sout_instance_t *p_sout, int i_query, void *p_args, void ...@@ -219,20 +219,20 @@ static int Capability( sout_instance_t *p_sout, int i_query, void *p_args, void
} }
} }
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; ts_stream_t *p_stream;
BITMAPINFOHEADER *p_bih; BITMAPINFOHEADER *p_bih;
WAVEFORMATEX *p_wf; WAVEFORMATEX *p_wf;
msg_Dbg( p_sout, "adding input" ); msg_Dbg( p_mux, "adding input" );
p_input->p_mux_data = (void*)p_stream = malloc( sizeof( ts_stream_t ) ); p_input->p_sys = (void*)p_stream = malloc( sizeof( ts_stream_t ) );
p_stream->i_pid = AllocatePID( p_mux ); p_stream->i_pid = AllocatePID( p_sys );
if( p_mux->i_pcr_pid == 0x1fff ) 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; p_stream->i_continuity_counter = 0;
...@@ -243,13 +243,13 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input ) ...@@ -243,13 +243,13 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
{ {
case VLC_FOURCC( 'm', 'p','g', 'v' ): case VLC_FOURCC( 'm', 'p','g', 'v' ):
p_stream->i_stream_type = 0x02; p_stream->i_stream_type = 0x02;
p_stream->i_stream_id = p_mux->i_stream_id_mpgv; p_stream->i_stream_id = p_sys->i_stream_id_mpgv;
p_mux->i_stream_id_mpgv++; p_sys->i_stream_id_mpgv++;
break; break;
case VLC_FOURCC( 'm', 'p','4', 'v' ): case VLC_FOURCC( 'm', 'p','4', 'v' ):
p_stream->i_stream_type = 0x10; p_stream->i_stream_type = 0x10;
p_stream->i_stream_id = 0xfa; 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_es_id = p_stream->i_pid;
p_stream->i_sl_predefined = 0x01; // NULL SL header p_stream->i_sl_predefined = 0x01; // NULL SL header
break; break;
...@@ -268,7 +268,7 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input ) ...@@ -268,7 +268,7 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
default: default:
return( -1 ); return( -1 );
} }
p_mux->i_video_bound++; p_sys->i_video_bound++;
p_bih = (BITMAPINFOHEADER*)p_input->input_format.p_format; p_bih = (BITMAPINFOHEADER*)p_input->input_format.p_format;
if( p_bih ) if( p_bih )
{ {
...@@ -305,25 +305,25 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input ) ...@@ -305,25 +305,25 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
case VLC_FOURCC( 'a', '5','2', ' ' ): case VLC_FOURCC( 'a', '5','2', ' ' ):
case VLC_FOURCC( 'a', '5','2', 'b' ): case VLC_FOURCC( 'a', '5','2', 'b' ):
p_stream->i_stream_type = 0x81; p_stream->i_stream_type = 0x81;
p_stream->i_stream_id = p_mux->i_stream_id_a52; p_stream->i_stream_id = p_sys->i_stream_id_a52;
p_mux->i_stream_id_a52++; p_sys->i_stream_id_a52++;
break; break;
case VLC_FOURCC( 'm', 'p','4', 'a' ): case VLC_FOURCC( 'm', 'p','4', 'a' ):
p_stream->i_stream_type = 0x11; p_stream->i_stream_type = 0x11;
p_stream->i_stream_id = 0xfa; 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_es_id = p_stream->i_pid;
p_stream->i_sl_predefined = 0x01; // NULL SL header p_stream->i_sl_predefined = 0x01; // NULL SL header
break; break;
case VLC_FOURCC( 'm', 'p','g', 'a' ): case VLC_FOURCC( 'm', 'p','g', 'a' ):
p_stream->i_stream_type = 0x04; p_stream->i_stream_type = 0x04;
p_stream->i_stream_id = p_mux->i_stream_id_mpga; p_stream->i_stream_id = p_sys->i_stream_id_mpga;
p_mux->i_stream_id_mpga++; p_sys->i_stream_id_mpga++;
break; break;
default: default:
return( -1 ); return( -1 );
} }
p_mux->i_audio_bound++; p_sys->i_audio_bound++;
p_wf = (WAVEFORMATEX*)p_input->input_format.p_format; p_wf = (WAVEFORMATEX*)p_input->input_format.p_format;
if( p_wf && p_wf->cbSize > 0 ) if( p_wf && p_wf->cbSize > 0 )
{ {
...@@ -344,20 +344,20 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input ) ...@@ -344,20 +344,20 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
return( -1 ); return( -1 );
} }
p_mux->i_ts_packet = 0; // force pat/pmt recreation p_sys->i_ts_packet = 0; // force pat/pmt recreation
p_mux->i_pat_version_number++; p_mux->i_pat_version_number %= 32; p_sys->i_pat_version_number++; p_sys->i_pat_version_number %= 32;
p_mux->i_pmt_version_number++; p_mux->i_pmt_version_number %= 32; p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
return( 0 ); 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; sout_mux_sys_t *p_sys = p_mux->p_sys;
ts_stream_t *p_stream; ts_stream_t *p_stream;
msg_Dbg( p_sout, "removing input" ); msg_Dbg( p_mux, "removing input" );
p_stream = (ts_stream_t*)p_input->p_mux_data; p_stream = (ts_stream_t*)p_input->p_sys;
if( p_stream->p_decoder_specific_info ) if( p_stream->p_decoder_specific_info )
{ {
...@@ -365,18 +365,18 @@ static int DelStream( sout_instance_t *p_sout, sout_input_t *p_input ) ...@@ -365,18 +365,18 @@ static int DelStream( sout_instance_t *p_sout, sout_input_t *p_input )
} }
if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb ) 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_sys->i_ts_packet = 0; // force pat/pmt recreation
p_mux->i_pat_version_number++; p_mux->i_pat_version_number %= 32; p_sys->i_pat_version_number++; p_sys->i_pat_version_number %= 32;
p_mux->i_pmt_version_number++; p_mux->i_pmt_version_number %= 32; p_sys->i_pmt_version_number++; p_sys->i_pmt_version_number %= 32;
return( 0 ); return( 0 );
} }
static int MuxGetStream( sout_instance_t *p_sout, static int MuxGetStream( sout_mux_t *p_mux,
int *pi_stream, int *pi_stream,
mtime_t *pi_dts ) mtime_t *pi_dts )
{ {
...@@ -384,11 +384,11 @@ static int MuxGetStream( sout_instance_t *p_sout, ...@@ -384,11 +384,11 @@ static int MuxGetStream( sout_instance_t *p_sout,
int i_stream; int i_stream;
int i; 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; 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 ) if( p_fifo->i_depth > 1 )
{ {
...@@ -567,9 +567,9 @@ static void SetTSDate( sout_buffer_t *p_ts, mtime_t i_dts, mtime_t i_length ) ...@@ -567,9 +567,9 @@ static void SetTSDate( sout_buffer_t *p_ts, mtime_t i_dts, mtime_t i_length )
} }
} }
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; int i_stream;
sout_buffer_t *p_pat, *p_pmt, *p_ts; sout_buffer_t *p_pat, *p_pmt, *p_ts;
...@@ -583,27 +583,27 @@ static int Mux( sout_instance_t *p_sout ) ...@@ -583,27 +583,27 @@ static int Mux( sout_instance_t *p_sout )
sout_fifo_t *p_fifo; sout_fifo_t *p_fifo;
sout_buffer_t *p_data; 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( 0 );
} }
p_input = p_sout->pp_inputs[i_stream]; p_input = p_mux->pp_inputs[i_stream];
p_fifo = p_input->p_fifo; 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 ); p_data = sout_FifoGet( p_fifo );
i_dts = p_data->i_dts; i_dts = p_data->i_dts;
i_length = p_data->i_length; i_length = p_data->i_length;
E_( EStoPES )( p_sout, &p_data, p_data, p_stream->i_stream_id, 1); E_( EStoPES )( p_mux->p_sout, &p_data, p_data, p_stream->i_stream_id, 1);
PEStoTS( p_sout, &p_data, p_data, p_stream ); 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 */ /* create pat/pmt */
GetPAT( p_sout, &p_pat ); GetPAT( p_mux, &p_pat );
GetPMT( p_sout, &p_pmt ); GetPMT( p_mux, &p_pmt );
p_ts = p_pat; p_ts = p_pat;
sout_BufferChain( &p_ts, p_pmt ); sout_BufferChain( &p_ts, p_pmt );
...@@ -614,10 +614,10 @@ static int Mux( sout_instance_t *p_sout ) ...@@ -614,10 +614,10 @@ static int Mux( sout_instance_t *p_sout )
p_ts = p_data; p_ts = p_data;
} }
p_mux->i_ts_packet++; p_sys->i_ts_packet++;
SetTSDate( p_ts, i_dts, i_length ); 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 ); return( 0 );
...@@ -708,14 +708,14 @@ static uint32_t CalculateCRC( uint8_t *p_begin, int i_count ) ...@@ -708,14 +708,14 @@ static uint32_t CalculateCRC( uint8_t *p_begin, int i_count )
} }
#if defined MODULE_NAME_IS_mux_ts #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_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; sout_buffer_t *p_pat;
bits_buffer_t bits; 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_pts = 0;
p_pat->i_dts = 0; p_pat->i_dts = 0;
...@@ -731,31 +731,31 @@ static int GetPAT( sout_instance_t *p_sout, ...@@ -731,31 +731,31 @@ static int GetPAT( sout_instance_t *p_sout,
bits_write( &bits, 12, 13 ); // XXX for one program only XXX bits_write( &bits, 12, 13 ); // XXX for one program only XXX
bits_write( &bits, 16, 0x01 ); // FIXME stream id bits_write( &bits, 16, 0x01 ); // FIXME stream id
bits_write( &bits, 2, 0x03 ); // FIXME 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, 1, 1 ); // current_next_indicator
bits_write( &bits, 8, 0 ); // section number bits_write( &bits, 8, 0 ); // section number
bits_write( &bits, 8, 0 ); // last section number bits_write( &bits, 8, 0 ); // last section number
bits_write( &bits, 16, 1 ); // program number bits_write( &bits, 16, 1 ); // program number
bits_write( &bits, 3, 0x07 ); // reserved 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) ); bits_write( &bits, 32, CalculateCRC( bits.p_data + 1, bits.i_data - 1) );
p_pat->i_size = bits.i_data; 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_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; sout_buffer_t *p_pmt;
bits_buffer_t bits; bits_buffer_t bits;
int i_stream; 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_pts = 0;
p_pmt->i_dts = 0; p_pmt->i_dts = 0;
...@@ -768,26 +768,26 @@ static int GetPMT( sout_instance_t *p_sout, ...@@ -768,26 +768,26 @@ static int GetPMT( sout_instance_t *p_sout,
bits_write( &bits, 1, 1 ); // section_syntax_indicator bits_write( &bits, 1, 1 ); // section_syntax_indicator
bits_write( &bits, 1, 0 ); // 0 bits_write( &bits, 1, 0 ); // 0
bits_write( &bits, 2, 0 ); // reserved FIXME 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, 16, 1 ); // FIXME program number
bits_write( &bits, 2, 0 ); // FIXME 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, 1, 0 ); // current_next_indicator
bits_write( &bits, 8, 0 ); // section number bits_write( &bits, 8, 0 ); // section number
bits_write( &bits, 8, 0 ); // last section number bits_write( &bits, 8, 0 ); // last section number
bits_write( &bits, 3, 0 ); // reserved 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, 4, 0 ); // reserved FIXME
bits_write( &bits, 12, 0 ); // program info len 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; 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, 8, p_stream->i_stream_type ); // stream_type
bits_write( &bits, 3, 0 ); // reserved bits_write( &bits, 3, 0 ); // reserved
...@@ -800,7 +800,7 @@ static int GetPMT( sout_instance_t *p_sout, ...@@ -800,7 +800,7 @@ static int GetPMT( sout_instance_t *p_sout,
p_pmt->i_size = bits.i_data; 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 #elif defined MODULE_NAME_IS_mux_ts_dvbpsi
...@@ -837,29 +837,29 @@ static sout_buffer_t *WritePSISection( sout_instance_t *p_sout, ...@@ -837,29 +837,29 @@ static sout_buffer_t *WritePSISection( sout_instance_t *p_sout,
return( p_first ); 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_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; sout_buffer_t *p_pat;
dvbpsi_pat_t pat; dvbpsi_pat_t pat;
dvbpsi_psi_section_t *p_section; dvbpsi_psi_section_t *p_section;
dvbpsi_InitPAT( &pat, dvbpsi_InitPAT( &pat,
0x01, // i_ts_id 0x01, // i_ts_id
p_mux->i_pat_version_number, p_sys->i_pat_version_number,
0); // b_current_next 0); // b_current_next
/* add all program (only one) */ /* add all program (only one) */
dvbpsi_PATAddProgram( &pat, dvbpsi_PATAddProgram( &pat,
1, // i_number 1, // i_number
p_mux->pmt.i_pid ); // i_pid p_sys->pmt.i_pid ); // i_pid
p_section = dvbpsi_GenPATSections( &pat, p_section = dvbpsi_GenPATSections( &pat,
0 ); // max program per section 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_DeletePSISections( p_section );
dvbpsi_EmptyPAT( &pat ); dvbpsi_EmptyPAT( &pat );
...@@ -877,25 +877,25 @@ static uint32_t GetDescriptorLength24b( int i_length ) ...@@ -877,25 +877,25 @@ static uint32_t GetDescriptorLength24b( int i_length )
return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 ); 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_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; sout_buffer_t *p_pmt;
dvbpsi_pmt_t pmt; dvbpsi_pmt_t pmt;
dvbpsi_pmt_es_t* p_es; dvbpsi_pmt_es_t *p_es;
dvbpsi_psi_section_t *p_section; dvbpsi_psi_section_t *p_section;
int i_stream; int i_stream;
dvbpsi_InitPMT( &pmt, dvbpsi_InitPMT( &pmt,
0x01, // program number 0x01, // program number
p_mux->i_pmt_version_number, p_sys->i_pmt_version_number,
1, // b_current_next 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]; uint8_t iod[4096];
bits_buffer_t bits; bits_buffer_t bits;
...@@ -918,10 +918,10 @@ static int GetPMT( sout_instance_t *p_sout, ...@@ -918,10 +918,10 @@ static int GetPMT( sout_instance_t *p_sout,
bits_write( &bits, 8, 0xfe ); // audioProfile (unspecified) bits_write( &bits, 8, 0xfe ); // audioProfile (unspecified)
bits_write( &bits, 8, 0xfe ); // visualProfile( // ) bits_write( &bits, 8, 0xfe ); // visualProfile( // )
bits_write( &bits, 8, 0xff ); // graphicProfile (no ) 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; 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 ) if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb )
{ {
...@@ -957,7 +957,7 @@ static int GetPMT( sout_instance_t *p_sout, ...@@ -957,7 +957,7 @@ static int GetPMT( sout_instance_t *p_sout,
bits_write( &bits, 8, 0x00 ); bits_write( &bits, 8, 0x00 );
bits_write( &bits, 6, 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, 0x00 ); // UpStream
bits_write( &bits, 1, 0x01 ); // reserved bits_write( &bits, 1, 0x01 ); // reserved
...@@ -998,7 +998,7 @@ static int GetPMT( sout_instance_t *p_sout, ...@@ -998,7 +998,7 @@ static int GetPMT( sout_instance_t *p_sout,
bits_align( &bits ); bits_align( &bits );
break; break;
default: default:
msg_Err( p_sout,"Unsupported SL profile => broken IOD"); msg_Err( p_mux,"Unsupported SL profile => broken IOD");
break; break;
} }
/* fix ESDescr length */ /* fix ESDescr length */
...@@ -1016,11 +1016,11 @@ static int GetPMT( sout_instance_t *p_sout, ...@@ -1016,11 +1016,11 @@ static int GetPMT( sout_instance_t *p_sout,
bits.p_data ); 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; 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_es = dvbpsi_PMTAddES( &pmt,
p_stream->i_stream_type, p_stream->i_stream_type,
...@@ -1067,9 +1067,9 @@ static int GetPMT( sout_instance_t *p_sout, ...@@ -1067,9 +1067,9 @@ static int GetPMT( sout_instance_t *p_sout,
p_section = dvbpsi_GenPMTSections( &pmt ); 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_DeletePSISections( p_section );
dvbpsi_EmptyPMT( &pmt ); dvbpsi_EmptyPMT( &pmt );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ogg.c * ogg.c
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -42,10 +42,10 @@ ...@@ -42,10 +42,10 @@
static int Open ( vlc_object_t * ); static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * ); static void Close ( vlc_object_t * );
static int Capability( sout_instance_t *, int, void *, void * ); static int Capability(sout_mux_t *, int, void *, void * );
static int AddStream( sout_instance_t *, sout_input_t * ); static int AddStream( sout_mux_t *, sout_input_t * );
static int DelStream( sout_instance_t *, sout_input_t * ); static int DelStream( sout_mux_t *, sout_input_t * );
static int Mux ( sout_instance_t * ); static int Mux ( sout_mux_t * );
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
...@@ -121,12 +121,12 @@ typedef struct ...@@ -121,12 +121,12 @@ typedef struct
} ogg_stream_t; } ogg_stream_t;
typedef struct sout_mux_s struct sout_mux_sys_t
{ {
int b_write_header; int b_write_header;
int i_streams; int i_streams;
} sout_mux_t; };
#define SetWLE( p, v ) _SetWLE( (uint8_t*)p, v) #define SetWLE( p, v ) _SetWLE( (uint8_t*)p, v)
static void _SetWLE( uint8_t *p, uint16_t i_dw ) static void _SetWLE( uint8_t *p, uint16_t i_dw )
...@@ -151,28 +151,28 @@ static void _SetQWLE( uint8_t *p, uint64_t i_qw ) ...@@ -151,28 +151,28 @@ static void _SetQWLE( uint8_t *p, uint64_t i_qw )
} }
static void OggSetDate( sout_buffer_t *, mtime_t , mtime_t ); 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: * Open:
*****************************************************************************/ *****************************************************************************/
static int Open( vlc_object_t *p_this ) 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;
sout_mux_t *p_mux; 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_mux->i_streams = 0; p_sys->i_streams = 0;
p_mux->b_write_header = VLC_TRUE; p_sys->b_write_header = VLC_TRUE;
p_sout->p_mux_data = (void*)p_mux; p_mux->p_sys = p_sys;
p_sout->pf_mux_capacity = Capability; p_mux->pf_capacity = Capability;
p_sout->pf_mux_addstream = AddStream; p_mux->pf_addstream = AddStream;
p_sout->pf_mux_delstream = DelStream; p_mux->pf_delstream = DelStream;
p_sout->pf_mux = Mux; p_mux->pf_mux = Mux;
p_sout->i_mux_preheader = 1; p_mux->i_preheader = 1;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -183,15 +183,15 @@ static int Open( vlc_object_t *p_this ) ...@@ -183,15 +183,15 @@ static int Open( vlc_object_t *p_this )
static void Close( vlc_object_t * p_this ) 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_this;
sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data; 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 ) switch( i_query )
{ {
...@@ -203,16 +203,16 @@ static int Capability( sout_instance_t *p_sout, int i_query, void *p_args, void ...@@ -203,16 +203,16 @@ static int Capability( sout_instance_t *p_sout, int i_query, void *p_args, void
} }
} }
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; ogg_stream_t *p_stream;
BITMAPINFOHEADER *p_bih; BITMAPINFOHEADER *p_bih;
WAVEFORMATEX *p_wf; WAVEFORMATEX *p_wf;
msg_Dbg( p_sout, "adding input" ); msg_Dbg( p_mux, "adding input" );
p_input->p_mux_data = (void*)p_stream = malloc( sizeof( ogg_stream_t ) ); 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_cat = p_input->input_format.i_cat;
p_stream->i_fourcc = p_input->input_format.i_fourcc; p_stream->i_fourcc = p_input->input_format.i_fourcc;
...@@ -257,7 +257,7 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input ) ...@@ -257,7 +257,7 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
} }
break; break;
default: default:
FREE( p_input->p_mux_data ); FREE( p_input->p_sys );
return( VLC_EGENERIC ); return( VLC_EGENERIC );
} }
break; break;
...@@ -302,48 +302,48 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input ) ...@@ -302,48 +302,48 @@ static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input )
break; break;
case VLC_FOURCC( 'v', 'o', 'r', 'b' ): case VLC_FOURCC( 'v', 'o', 'r', 'b' ):
default: default:
FREE( p_input->p_mux_data ); FREE( p_input->p_sys );
return( VLC_EGENERIC ); return( VLC_EGENERIC );
} }
break; break;
default: default:
FREE( p_input->p_mux_data ); FREE( p_input->p_sys );
return( VLC_EGENERIC ); return( VLC_EGENERIC );
} }
ogg_stream_init (&p_stream->os, rand ()); ogg_stream_init (&p_stream->os, rand ());
p_mux->i_streams++; p_sys->i_streams++;
return( VLC_SUCCESS ); 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; sout_buffer_t *p_og;
msg_Dbg( p_sout, "removing input" ); msg_Dbg( p_mux, "removing input" );
/* flush all remaining data */ /* 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 ) if( p_og )
{ {
OggSetDate( p_og, p_stream->i_dts, p_stream->i_length ); 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 ); ogg_stream_clear( &p_stream->os );
FREE( p_input->p_mux_data ); FREE( p_input->p_sys );
return( 0 ); return( 0 );
} }
/* /*
* TODO move this function to src/stream_output.c (used by nearly all muxers) * 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, int *pi_stream,
mtime_t *pi_dts ) mtime_t *pi_dts )
{ {
...@@ -351,11 +351,11 @@ static int MuxGetStream( sout_instance_t *p_sout, ...@@ -351,11 +351,11 @@ static int MuxGetStream( sout_instance_t *p_sout,
int i_stream; int i_stream;
int i; 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; 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 ) if( p_fifo->i_depth > 1 )
{ {
...@@ -385,7 +385,7 @@ static int MuxGetStream( sout_instance_t *p_sout, ...@@ -385,7 +385,7 @@ static int MuxGetStream( sout_instance_t *p_sout,
} }
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, ogg_stream_state *p_os,
mtime_t i_pts ) mtime_t i_pts )
{ {
...@@ -402,7 +402,7 @@ static sout_buffer_t *OggStreamFlush( sout_instance_t *p_sout, ...@@ -402,7 +402,7 @@ static sout_buffer_t *OggStreamFlush( sout_instance_t *p_sout,
break; break;
} }
i_size = og.header_len + og.body_len; 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, memcpy( p_og->p_buffer,
og.header, og.header,
...@@ -422,7 +422,7 @@ static sout_buffer_t *OggStreamFlush( sout_instance_t *p_sout, ...@@ -422,7 +422,7 @@ static sout_buffer_t *OggStreamFlush( sout_instance_t *p_sout,
return( p_og_first ); 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, ogg_stream_state *p_os,
mtime_t i_pts ) mtime_t i_pts )
{ {
...@@ -439,7 +439,7 @@ static sout_buffer_t *OggStreamPageOut( sout_instance_t *p_sout, ...@@ -439,7 +439,7 @@ static sout_buffer_t *OggStreamPageOut( sout_instance_t *p_sout,
break; break;
} }
i_size = og.header_len + og.body_len; 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, memcpy( p_og->p_buffer,
og.header, og.header,
...@@ -459,7 +459,7 @@ static sout_buffer_t *OggStreamPageOut( sout_instance_t *p_sout, ...@@ -459,7 +459,7 @@ static sout_buffer_t *OggStreamPageOut( sout_instance_t *p_sout,
return( p_og_first ); 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_hdr = NULL;
sout_buffer_t *p_og; sout_buffer_t *p_og;
...@@ -467,11 +467,11 @@ static sout_buffer_t *OggCreateHeader( sout_instance_t *p_sout, mtime_t i_dts ) ...@@ -467,11 +467,11 @@ static sout_buffer_t *OggCreateHeader( sout_instance_t *p_sout, mtime_t i_dts )
int i; int i;
/* write header for each stream */ /* 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; 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' ) ) if( p_stream->i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )
{ {
...@@ -508,7 +508,7 @@ static sout_buffer_t *OggCreateHeader( sout_instance_t *p_sout, mtime_t i_dts ) ...@@ -508,7 +508,7 @@ static sout_buffer_t *OggCreateHeader( sout_instance_t *p_sout, mtime_t i_dts )
#endif #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 ); sout_BufferChain( &p_hdr, p_og );
} }
...@@ -542,21 +542,21 @@ static void OggSetDate( sout_buffer_t *p_og, mtime_t i_dts, mtime_t i_length ) ...@@ -542,21 +542,21 @@ static void OggSetDate( sout_buffer_t *p_og, mtime_t i_dts, mtime_t i_length )
} }
} }
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; sout_buffer_t *p_og = NULL;
int i_stream; int i_stream;
mtime_t i_dts; 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 ); return( VLC_SUCCESS );
} }
sout_BufferChain( &p_og, OggCreateHeader( p_sout, i_dts ) ); sout_BufferChain( &p_og, OggCreateHeader( p_mux, i_dts ) );
p_mux->b_write_header = VLC_FALSE; p_sys->b_write_header = VLC_FALSE;
} }
for( ;; ) for( ;; )
...@@ -566,17 +566,17 @@ static int Mux ( sout_instance_t *p_sout ) ...@@ -566,17 +566,17 @@ static int Mux ( sout_instance_t *p_sout )
sout_buffer_t *p_data; sout_buffer_t *p_data;
ogg_packet op; ogg_packet op;
if( MuxGetStream( p_sout, &i_stream, &i_dts) < 0 ) if( MuxGetStream( p_mux, &i_stream, &i_dts) < 0 )
{ {
return( VLC_SUCCESS ); return( VLC_SUCCESS );
} }
p_input = p_sout->pp_inputs[i_stream]; p_input = p_mux->pp_inputs[i_stream];
p_stream = (ogg_stream_t*)p_input->p_mux_data; p_stream = (ogg_stream_t*)p_input->p_sys;
p_data = sout_FifoGet( p_input->p_fifo ); 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 p_data->p_buffer[0] = PACKET_IS_SYNCPOINT; // FIXME
op.packet = p_data->p_buffer; op.packet = p_data->p_buffer;
...@@ -596,7 +596,7 @@ static int Mux ( sout_instance_t *p_sout ) ...@@ -596,7 +596,7 @@ static int Mux ( sout_instance_t *p_sout )
ogg_stream_packetin( &p_stream->os, &op ); ogg_stream_packetin( &p_stream->os, &op );
sout_BufferChain( &p_og, sout_BufferChain( &p_og,
OggStreamPageOut( p_sout, OggStreamPageOut( p_mux,
&p_stream->os, &p_stream->os,
p_data->i_pts ) ); p_data->i_pts ) );
...@@ -605,7 +605,7 @@ static int Mux ( sout_instance_t *p_sout ) ...@@ -605,7 +605,7 @@ static int Mux ( sout_instance_t *p_sout )
OggSetDate( p_og, p_stream->i_dts, p_stream->i_length ); OggSetDate( p_og, p_stream->i_dts, p_stream->i_length );
p_stream->i_dts = -1; p_stream->i_dts = -1;
p_stream->i_length = 0;; 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_og = NULL;
} }
...@@ -618,7 +618,7 @@ static int Mux ( sout_instance_t *p_sout ) ...@@ -618,7 +618,7 @@ static int Mux ( sout_instance_t *p_sout )
p_stream->i_length += p_data->i_length; 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 ); return( VLC_SUCCESS );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* a52.c * a52.c
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org> * Eric Petit <titer@videolan.org>
...@@ -44,7 +44,7 @@ typedef struct packetizer_s ...@@ -44,7 +44,7 @@ typedef struct packetizer_s
bit_stream_t bit_stream; bit_stream_t bit_stream;
/* Output properties */ /* Output properties */
sout_input_t *p_sout_input; sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format; sout_packet_format_t output_format;
uint64_t i_samplescount; uint64_t i_samplescount;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* copy.c * copy.c
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org> * Eric Petit <titer@videolan.org>
...@@ -44,7 +44,7 @@ typedef struct packetizer_thread_s ...@@ -44,7 +44,7 @@ typedef struct packetizer_thread_s
decoder_fifo_t *p_fifo; decoder_fifo_t *p_fifo;
/* Output properties */ /* Output properties */
sout_input_t *p_sout_input; sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format; sout_packet_format_t output_format;
mtime_t i_pts_start; mtime_t i_pts_start;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mpeg4audio.c * mpeg4audio.c
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -59,7 +59,7 @@ typedef struct packetizer_thread_s ...@@ -59,7 +59,7 @@ typedef struct packetizer_thread_s
bit_stream_t bit_stream; bit_stream_t bit_stream;
/* Output properties */ /* Output properties */
sout_input_t *p_sout_input; sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format; sout_packet_format_t output_format;
mtime_t i_pts_start; mtime_t i_pts_start;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mpeg4video.c * mpeg4video.c
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org> * Eric Petit <titer@videolan.org>
...@@ -45,7 +45,7 @@ typedef struct packetizer_thread_s ...@@ -45,7 +45,7 @@ typedef struct packetizer_thread_s
decoder_fifo_t *p_fifo; decoder_fifo_t *p_fifo;
/* Output properties */ /* Output properties */
sout_input_t *p_sout_input; sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format; sout_packet_format_t output_format;
mtime_t i_pts_start; mtime_t i_pts_start;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mpegaudio.c * mpegaudio.c
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org> * Eric Petit <titer@videolan.org>
...@@ -44,7 +44,7 @@ typedef struct packetizer_s ...@@ -44,7 +44,7 @@ typedef struct packetizer_s
bit_stream_t bit_stream; bit_stream_t bit_stream;
/* Output properties */ /* Output properties */
sout_input_t *p_sout_input; sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format; sout_packet_format_t output_format;
uint64_t i_samplescount; uint64_t i_samplescount;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mpegvideo.c * mpegvideo.c
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org> * Eric Petit <titer@videolan.org>
...@@ -44,7 +44,7 @@ typedef struct packetizer_s ...@@ -44,7 +44,7 @@ typedef struct packetizer_s
bit_stream_t bit_stream; bit_stream_t bit_stream;
/* Output properties */ /* Output properties */
sout_input_t *p_sout_input; sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format; sout_packet_format_t output_format;
mtime_t i_last_dts; mtime_t i_last_dts;
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
* stream_output.c : stream output module * stream_output.c : stream output module
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Laurent Aimar <fenrir@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 * 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 * it under the terms of the GNU General Public License as published by
...@@ -37,9 +37,18 @@ ...@@ -37,9 +37,18 @@
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static int InitInstance ( sout_instance_t * ); static int InstanceNewOutput ( sout_instance_t *, char * );
static int InstanceMuxNew ( sout_instance_t *,
struct sout_instance_sys_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 /* if muxer doesn't support adding stream at any time then we first wait
* for stream then we refuse all stream and start muxing */ * for stream then we refuse all stream and start muxing */
...@@ -48,8 +57,93 @@ struct sout_instance_sys_t ...@@ -48,8 +57,93 @@ struct sout_instance_sys_t
/* we wait one second after first stream added */ /* we wait one second after first stream added */
mtime_t i_add_stream_start; 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_NewInstance: creates a new stream output instance
...@@ -57,7 +151,8 @@ struct sout_instance_sys_t ...@@ -57,7 +151,8 @@ struct sout_instance_sys_t
sout_instance_t * __sout_NewInstance ( vlc_object_t *p_parent, sout_instance_t * __sout_NewInstance ( vlc_object_t *p_parent,
char * psz_dest ) char * psz_dest )
{ {
sout_instance_t * p_sout; sout_instance_t *p_sout;
char *psz_dup, *psz_parser, *psz_pos;
/* Allocate descriptor */ /* Allocate descriptor */
p_sout = vlc_object_create( p_parent, VLC_OBJECT_SOUT ); p_sout = vlc_object_create( p_parent, VLC_OBJECT_SOUT );
...@@ -67,61 +162,142 @@ sout_instance_t * __sout_NewInstance ( vlc_object_t *p_parent, ...@@ -67,61 +162,142 @@ sout_instance_t * __sout_NewInstance ( vlc_object_t *p_parent,
return NULL; 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;
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;
if ( InitInstance( p_sout ) == -1 ) 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 ); vlc_object_destroy( p_sout );
return NULL; return( NULL );
} }
vlc_object_attach( p_sout, p_parent ); vlc_object_attach( p_sout, p_parent );
return p_sout; 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 * 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>] */ /* Parse dest string. Syntax : [[<access>][/<mux>]:][<dest>] */
/* This code is identical to input.c:InitThread. FIXME : factorize it ? */ /* 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 != ':' ) while( *psz_parser && *psz_parser != ':' )
{ {
psz_parser++; psz_parser++;
} }
#if defined( WIN32 ) || defined( UNDER_CE ) #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", msg_Warn( p_sout, "drive letter %c: found in source string",
*p_sout->psz_dest ) ; *psz_dup ) ;
psz_parser = ""; psz_parser = "";
} }
#endif #endif
if( !*psz_parser ) if( !*psz_parser )
{ {
p_sout->psz_access = p_sout->psz_mux = ""; psz_access = psz_mux = "";
p_sout->psz_name = p_sout->psz_dest; psz_name = psz_dup;
} }
else else
{ {
...@@ -133,25 +309,25 @@ static int InitInstance( sout_instance_t * p_sout ) ...@@ -133,25 +309,25 @@ static int InitInstance( sout_instance_t * p_sout )
psz_parser += 2 ; psz_parser += 2 ;
} }
p_sout->psz_name = psz_parser ; psz_name = psz_parser ;
/* Come back to parse the access and mux plug-ins */ /* Come back to parse the access and mux plug-ins */
psz_parser = p_sout->psz_dest; psz_parser = psz_dup;
if( !*psz_parser ) if( !*psz_parser )
{ {
/* No access */ /* No access */
p_sout->psz_access = ""; psz_access = "";
} }
else if( *psz_parser == '/' ) else if( *psz_parser == '/' )
{ {
/* No access */ /* No access */
p_sout->psz_access = ""; psz_access = "";
psz_parser++; psz_parser++;
} }
else else
{ {
p_sout->psz_access = psz_parser; psz_access = psz_parser;
while( *psz_parser && *psz_parser != '/' ) while( *psz_parser && *psz_parser != '/' )
{ {
...@@ -167,91 +343,93 @@ static int InitInstance( sout_instance_t * p_sout ) ...@@ -167,91 +343,93 @@ static int InitInstance( sout_instance_t * p_sout )
if( !*psz_parser ) if( !*psz_parser )
{ {
/* No mux */ /* No mux */
p_sout->psz_mux = ""; psz_mux = "";
} }
else else
{ {
p_sout->psz_mux = psz_parser; psz_mux = psz_parser;
} }
} }
msg_Dbg( p_sout, "access `%s', mux `%s', name `%s'", 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
/* 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 )
{
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;
}
mrl_Parse( &mrl, psz_dest );
msg_Dbg( p_sout, "access `%s', mux `%s', name `%s'",
mrl.psz_access, mrl.psz_way, mrl.psz_name );
/* Find and open appropriate mux module */ vlc_mutex_lock( &p_sout->lock );
p_sout->p_mux = /* *** create mux *** */
module_Need( p_sout, "sout mux", p_sout->psz_mux );
if( p_sout->p_mux == NULL ) if( InstanceMuxNew( p_sout, mrl.psz_way, mrl.psz_access, mrl.psz_name ) )
{ {
msg_Err( p_sout, "no suitable mux module for `%s/%s://%s'", msg_Err( p_sout, "cannot create sout chain for %s/%s://%s",
p_sout->psz_access, p_sout->psz_mux, p_sout->psz_name ); mrl.psz_access, mrl.psz_way, mrl.psz_name );
sout_AccessOutDelete( p_sout->p_access ); mrl_Clean( &mrl );
return -1; vlc_mutex_unlock( &p_sout->lock );
} return( VLC_EGENERIC );
if( p_sout->pf_mux_capacity )
{
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 ) mrl_Clean( &mrl );
/* *** finish all setup *** */
if( p_sout->psz_sout )
{ {
msg_Dbg( p_sout, "muxer support adding stream at any time" ); p_sout->psz_sout =
p_sout->p_sys->b_add_stream_any_time = VLC_TRUE; realloc( p_sout->psz_sout,
p_sout->p_sys->b_waiting_stream = VLC_FALSE; strlen( p_sout->psz_sout ) +2+1+ strlen( psz_dest ) );
strcat( p_sout->psz_sout, "#" );
strcat( p_sout->psz_sout, psz_dest );
} }
else else
{ {
p_sout->p_sys->b_add_stream_any_time = VLC_FALSE; p_sout->psz_sout = strdup( psz_dest );
p_sout->p_sys->b_waiting_stream = VLC_TRUE;
} }
} psz_dup = strdup( psz_dest );
p_sout->i_nb_inputs = 0; TAB_APPEND( p_sout->i_nb_dest, p_sout->ppsz_dest, psz_dup );
p_sout->pp_inputs = NULL; vlc_mutex_unlock( &p_sout->lock );
return 0; msg_Dbg( p_sout, "complete sout `%s'", p_sout->psz_sout );
}
return VLC_SUCCESS;
}
/***************************************************************************** static int InstanceMuxNew ( sout_instance_t *p_sout,
* sout_DeleteInstance: delete a previously allocated instance char *psz_mux, char *psz_access, char *psz_name )
*****************************************************************************/
void sout_DeleteInstance( sout_instance_t * p_sout )
{ {
/* Unlink object */ sout_access_out_t *p_access;
vlc_object_detach( p_sout ); sout_mux_t *p_mux;
if( p_sout->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 * sout_AccessOutNew: allocate a new access out
*****************************************************************************/ *****************************************************************************/
...@@ -279,8 +457,10 @@ sout_access_out_t *sout_AccessOutNew( sout_instance_t *p_sout, ...@@ -279,8 +457,10 @@ sout_access_out_t *sout_AccessOutNew( sout_instance_t *p_sout,
if( !p_access->p_module ) if( !p_access->p_module )
{ {
free( p_access->psz_access );
free( p_access->psz_name );
vlc_object_destroy( p_access ); vlc_object_destroy( p_access );
p_access = NULL; return( NULL );
} }
return p_access; return p_access;
...@@ -318,15 +498,209 @@ int sout_AccessOutWrite( sout_access_out_t *p_access, sout_buffer_t *p_buffer ) ...@@ -318,15 +498,209 @@ int sout_AccessOutWrite( sout_access_out_t *p_access, sout_buffer_t *p_buffer )
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_packetizer_input_t *__sout_InputNew( vlc_object_t *p_this,
sout_packet_format_t *p_format ) sout_packet_format_t *p_format )
{ {
sout_instance_t *p_sout = NULL; sout_instance_t *p_sout = NULL;
sout_input_t *p_input; sout_packetizer_input_t *p_input;
int i_try; int i_try;
int i_mux;
vlc_bool_t b_accepted = VLC_FALSE;
/* search an stream output */ /* search an stream output */
for( i_try = 0; i_try < 12; i_try++ ) for( i_try = 0; i_try < 12; i_try++ )
...@@ -348,59 +722,55 @@ sout_input_t *__sout_InputNew( vlc_object_t *p_this, ...@@ -348,59 +722,55 @@ sout_input_t *__sout_InputNew( vlc_object_t *p_this,
msg_Err( p_this, "cannot find any stream ouput" ); msg_Err( p_this, "cannot find any stream ouput" );
return( NULL ); 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" ); 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 ) );
/* *** create a packetizer input *** */
p_input = malloc( sizeof( sout_packetizer_input_t ) );
p_input->p_sout = p_sout; p_input->p_sout = p_sout;
vlc_mutex_init( p_sout, &p_input->lock ); 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, memcpy( &p_input->input_format,
p_format, p_format,
sizeof( sout_packet_format_t ) ); 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_object_release( p_sout );
return p_input;
}
vlc_mutex_lock( &p_sout->lock ); vlc_mutex_lock( &p_sout->lock );
if( p_sout->i_nb_inputs == 0 ) /* *** add this input to all muxers *** */
for( i_mux = 0; i_mux < p_sout->i_nb_mux; i_mux++ )
{ {
p_sout->pp_inputs = malloc( sizeof( sout_input_t * ) ); sout_input_t *p_mux_input;
} #define p_mux p_sout->pp_mux[i_mux]
else
p_mux_input = MuxAddStream( p_mux, p_format );
if( p_mux_input )
{ {
p_sout->pp_inputs = realloc( p_sout->pp_inputs, TAB_APPEND( p_input->i_nb_inputs, p_input->pp_inputs, p_mux_input );
sizeof( sout_input_t * ) * TAB_APPEND( p_input->i_nb_mux, p_input->pp_mux, p_mux );
( p_sout->i_nb_inputs + 1 ) );
b_accepted = VLC_TRUE;
}
#undef p_mux
} }
p_sout->pp_inputs[p_sout->i_nb_inputs] = p_input;
p_sout->i_nb_inputs++;
if( p_sout->pf_mux_addstream( p_sout, p_input ) < 0 ) if( !b_accepted )
{ {
msg_Err( p_sout, "cannot add this stream" ); /* all muxer refuse this stream, so delete it */
free( p_input );
vlc_mutex_unlock( &p_sout->lock ); vlc_mutex_unlock( &p_sout->lock );
sout_InputDelete( p_input ); vlc_object_release( p_sout );
vlc_mutex_lock( &p_sout->lock ); return( NULL );
p_input = NULL;
} }
TAB_APPEND( p_sout->i_nb_inputs, p_sout->pp_inputs, p_input );
vlc_mutex_unlock( &p_sout->lock ); vlc_mutex_unlock( &p_sout->lock );
}
vlc_object_release( p_sout ); vlc_object_release( p_sout );
...@@ -408,96 +778,65 @@ sout_input_t *__sout_InputNew( vlc_object_t *p_this, ...@@ -408,96 +778,65 @@ sout_input_t *__sout_InputNew( vlc_object_t *p_this,
} }
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; sout_instance_t *p_sout = p_input->p_sout;
int i_input; int i_input;
msg_Dbg( p_sout, "removing an input" ); msg_Dbg( p_sout, "removing an input" );
vlc_mutex_lock( &p_sout->lock ); vlc_mutex_lock( &p_sout->lock );
sout_FifoDestroy( p_sout, p_input->p_fifo ); /* *** remove this input to all muxers *** */
vlc_mutex_destroy( &p_input->lock ); for( i_input = 0; i_input < p_input->i_nb_inputs; i_input++ )
for( i_input = 0; i_input < p_sout->i_nb_inputs; i_input++ )
{ {
if( p_sout->pp_inputs[i_input] == p_input ) MuxDeleteStream( p_input->pp_mux[i_input], p_input->pp_inputs[i_input] );
{
break;
}
}
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 */ TAB_REMOVE( p_sout->i_nb_inputs, p_sout->pp_inputs, p_input );
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--;
if( p_sout->i_nb_inputs == 0 ) free( p_input->pp_inputs );
{ free( p_input->pp_mux );
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 ); free( p_input );
vlc_mutex_unlock( &p_sout->lock ); vlc_mutex_unlock( &p_sout->lock );
return( 0 ); 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, /* msg_Dbg( p_input->p_sout,
"send buffer, size:%d", p_buffer->i_size ); */ "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 ); MuxSendBuffer( p_input->pp_mux[p_input->i_nb_inputs-1],
p_input->p_sout->pf_mux( p_input->p_sout ); p_input->pp_inputs[p_input->i_nb_inputs-1],
p_buffer );
vlc_mutex_unlock( &p_input->p_sout->lock ); vlc_mutex_unlock( &p_input->p_sout->lock );
} }
else else
{ {
sout_BufferDelete( p_input->p_sout, p_buffer ); sout_BufferDelete( p_input->p_sout, p_buffer );
} }
return( 0 ); return( 0 );
} }
...@@ -612,26 +951,26 @@ sout_buffer_t *sout_FifoShow( sout_fifo_t *p_fifo ) ...@@ -612,26 +951,26 @@ sout_buffer_t *sout_FifoShow( sout_fifo_t *p_fifo )
sout_buffer_t *sout_BufferNew( sout_instance_t *p_sout, size_t i_size ) sout_buffer_t *sout_BufferNew( sout_instance_t *p_sout, size_t i_size )
{ {
sout_buffer_t *p_buffer; sout_buffer_t *p_buffer;
size_t i_prehader; size_t i_preheader;
#ifdef DEBUG_BUFFER #ifdef DEBUG_BUFFER
msg_Dbg( p_sout, "allocating an new buffer, size:%d", (uint32_t)i_size ); msg_Dbg( p_sout, "allocating an new buffer, size:%d", (uint32_t)i_size );
#endif #endif
p_buffer = malloc( sizeof( sout_buffer_t ) ); p_buffer = malloc( sizeof( sout_buffer_t ) );
i_prehader = p_sout->i_mux_preheader; i_preheader = p_sout->i_preheader;
if( i_size > 0 ) if( i_size > 0 )
{ {
p_buffer->p_allocated_buffer = malloc( i_size + i_prehader ); p_buffer->p_allocated_buffer = malloc( i_size + i_preheader );
p_buffer->p_buffer = p_buffer->p_allocated_buffer + i_prehader; p_buffer->p_buffer = p_buffer->p_allocated_buffer + i_preheader;
} }
else else
{ {
p_buffer->p_allocated_buffer = NULL; p_buffer->p_allocated_buffer = NULL;
p_buffer->p_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_buffer_size = i_size;
p_buffer->i_size = i_size; p_buffer->i_size = i_size;
...@@ -646,7 +985,7 @@ sout_buffer_t *sout_BufferNew( sout_instance_t *p_sout, size_t i_size ) ...@@ -646,7 +985,7 @@ sout_buffer_t *sout_BufferNew( sout_instance_t *p_sout, size_t i_size )
} }
int sout_BufferRealloc( sout_instance_t *p_sout, sout_buffer_t *p_buffer, size_t 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 #ifdef DEBUG_BUFFER
msg_Dbg( p_sout, msg_Dbg( p_sout,
...@@ -655,9 +994,9 @@ int sout_BufferRealloc( sout_instance_t *p_sout, sout_buffer_t *p_buffer, size_t ...@@ -655,9 +994,9 @@ int sout_BufferRealloc( sout_instance_t *p_sout, sout_buffer_t *p_buffer, size_t
(uint32_t)i_size ); (uint32_t)i_size );
#endif #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" ); msg_Err( p_sout, "realloc failed" );
p_buffer->i_allocated_size = 0; p_buffer->i_allocated_size = 0;
...@@ -666,9 +1005,9 @@ int sout_BufferRealloc( sout_instance_t *p_sout, sout_buffer_t *p_buffer, size_t ...@@ -666,9 +1005,9 @@ int sout_BufferRealloc( sout_instance_t *p_sout, sout_buffer_t *p_buffer, size_t
p_buffer->p_buffer = NULL; p_buffer->p_buffer = NULL;
return( -1 ); 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; p_buffer->i_buffer_size = i_size;
return( 0 ); return( 0 );
...@@ -741,3 +1080,218 @@ void sout_BufferChain( sout_buffer_t **pp_chain, ...@@ -741,3 +1080,218 @@ void sout_BufferChain( sout_buffer_t **pp_chain,
p->p_next = p_buffer; 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 );
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment