Commit 4dec9682 authored by Laurent Aimar's avatar Laurent Aimar

* all: new sout scheme. Now a chain of module are created that can

modify/apply on all streams, --sout has the same behavour expect when
starting with a '#'.

 With a starting '#' you can specify a chain of modules, it's still
unstable but a lot more powerfull.
 You have access to duplicate(that duplicate all stream), transcode
(using only ffmpeg), standard/std and es (that apply muxers and access),
and display. You could chain them with ':' and specify options with
{option1=value,option2=value[,...]}.

ex: * to stream and see the stream to udp/ts:ip
 --sout '#duplicate{dst=display,dst=std{access=udp,mux=ts,url=ip}}'
    * to transcode,see and stream
 --sout '#transcode{acodec=mpga}:duplicate{dst=display,dst=std{access=udp,mux=ts,url=ip}}'

 Without a starting '#', the url is converted into '#std{acces=,mux=,url}'
Test and report bugs :)
parent 1bab4d17
......@@ -334,6 +334,7 @@ AC_CHECK_LIB(m,cos,
LDFLAGS_a52tofloat32="${LDFLAGS_a52tofloat32} -lm")
AC_CHECK_LIB(m,pow,
LDFLAGS_ffmpeg="${LDFLAGS_ffmpeg} -lm"
LDFLAGS_stream_out_transcode="${LDFLAGS_stream_out_transcode} -lm"
LDFLAGS_imdct="${LDFLAGS_imdct} -lm"
LDFLAGS_imdct3dn="${LDFLAGS_imdct3dn} -lm"
LDFLAGS_imdctsse="${LDFLAGS_imdctsse} -lm"
......@@ -1017,7 +1018,8 @@ then
PLUGINS="${PLUGINS} packetizer_mpeg4video packetizer_mpeg4audio"
PLUGINS="${PLUGINS} packetizer_copy"
PLUGINS="${PLUGINS} vout_encoder"
PLUGINS="${PLUGINS} stream_out_dummy stream_out_standard stream_out_es"
PLUGINS="${PLUGINS} stream_out_duplicate stream_out_display"
dnl Ogg/ogm
AC_CHECK_HEADERS(ogg/ogg.h, [
......@@ -1510,6 +1512,10 @@ then
then
CPPFLAGS_ffmpeg="${CPPFLAGS_ffmpeg} -I${with_ffmpeg}/include/ffmpeg"
LDFLAGS_ffmpeg="${LDFLAGS_ffmpeg} -L${with_ffmpeg}/lib"
CPPFLAGS_stream_out_transcode="${CPPFLAGS_stream_out_transcode} -I${with_ffmpeg}/include/ffmpeg"
LDFLAGS_stream_out_transcode="${LDFLAGS_stream_out_transcode} -L${with_ffmpeg}/lib"
fi
dnl Add postprocessing modules
......@@ -1538,9 +1544,13 @@ then
then
dnl Use a custom libffmpeg
AC_MSG_RESULT(${real_ffmpeg_tree}/libavcodec/libavcodec.a)
BUILTINS="${BUILTINS} ffmpeg"
BUILTINS="${BUILTINS} ffmpeg stream_out_transcode"
LDFLAGS_ffmpeg="${LDFLAGS_ffmpeg} -L${real_ffmpeg_tree}/libavcodec -lavcodec"
CPPFLAGS_ffmpeg="${CPPFLAGS_ffmpeg} -I${real_ffmpeg_tree}/libavcodec"
LDFLAGS_stream_out_transcode="${LDFLAGS_stream_out_transcode} -L${real_ffmpeg_tree}/libavcodec -lavcodec"
CPPFLAGS_stream_out_transcode="${CPPFLAGS_stream_out_transcode} -I${real_ffmpeg_tree}/libavcodec"
else
dnl The given libavcodec wasn't built
AC_MSG_RESULT(no)
......@@ -1550,8 +1560,9 @@ then
CPPFLAGS="${CPPFLAGS_save} ${CPPFLAGS_ffmpeg}"
LDFLAGS="${LDFLAGS_save} ${LDFLAGS_ffmpeg}"
AC_CHECK_LIB(avcodec, avcodec_init, [
BUILTINS="${BUILTINS} ffmpeg"
LDFLAGS_ffmpeg="${LDFLAGS_ffmpeg} -lavcodec" ],
BUILTINS="${BUILTINS} ffmpeg stream_out_transcode"
LDFLAGS_ffmpeg="${LDFLAGS_ffmpeg} -lavcodec"
LDFLAGS_stream_out_transcode="${LDFLAGS_stream_out_transcode} -lavcodec" ],
[ AC_MSG_ERROR([Cannot find libavcodec library...]) ])
LDFLAGS="${LDFLAGS_save}"
CPPFLAGS="${CPPFLAGS_save}"
......
......@@ -4,7 +4,7 @@
* control the pace of reading.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-intf.h,v 1.87 2003/03/24 17:15:29 gbazin Exp $
* $Id: input_ext-intf.h,v 1.88 2003/04/13 20:00:20 fenrir Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -71,6 +71,9 @@ struct es_descriptor_t
count_t c_packets; /* total packets read */
count_t c_invalid_packets; /* invalid packets read */
/* XXX hack: to force a decoder instead of mode based on sout */
vlc_bool_t b_force_decoder;
};
/* Special PID values - note that the PID is only on 13 bits, and that values
......
......@@ -2,7 +2,7 @@
* stream_output.h : stream output module
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: stream_output.h,v 1.9 2003/03/11 19:02:30 fenrir Exp $
* $Id: stream_output.h,v 1.10 2003/04/13 20:00:20 fenrir Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Laurent Aimar <fenrir@via.ecp.fr>
......@@ -57,12 +57,24 @@ struct sout_buffer_t
struct sout_buffer_t *p_next;
};
struct sout_packet_format_t
struct sout_format_t
{
int i_cat; // AUDIO_ES, VIDEO_ES, SPU_ES
int i_cat;
vlc_fourcc_t i_fourcc;
void *p_format; // WAVEFORMATEX or BITMAPINFOHEADER
/* audio */
int i_sample_rate;
int i_channels;
int i_block_align;
/* video */
int i_width;
int i_height;
int i_bitrate;
int i_extra_data;
uint8_t *p_extra_data;
};
struct sout_fifo_t
......@@ -75,39 +87,36 @@ struct sout_fifo_t
sout_buffer_t **pp_last;
};
typedef struct sout_stream_id_t sout_stream_id_t;
/* for mux */
struct sout_input_t
{
// vlc_mutex_t lock;
sout_instance_t *p_sout;
sout_packet_format_t input_format;
sout_format_t *p_fmt;
sout_fifo_t *p_fifo;
void *p_sys;
};
/* for packetizr */
/* for packetizer */
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;
sout_format_t *p_fmt;
sout_stream_id_t *id;
};
#define SOUT_METHOD_NONE 0x00
#define SOUT_METHOD_FILE 0x10
#define SOUT_METHOD_NETWORK 0x20
typedef struct sout_access_out_sys_t sout_access_out_sys_t;
struct sout_access_out_t
{
VLC_COMMON_MEMBERS
......@@ -180,36 +189,129 @@ struct sout_mux_t
mtime_t i_add_stream_start;
};
struct sout_cfg_t
{
sout_cfg_t *p_next;
char *psz_name;
char *psz_value;
};
typedef struct sout_stream_sys_t sout_stream_sys_t;
struct sout_stream_t
{
VLC_COMMON_MEMBERS
module_t *p_module;
sout_instance_t *p_sout;
char *psz_name;
sout_cfg_t *p_cfg;
char *psz_next;
/* add, remove a stream */
sout_stream_id_t * (*pf_add) ( sout_stream_t *, sout_format_t * );
int (*pf_del) ( sout_stream_t *, sout_stream_id_t * );
/* manage a packet */
int (*pf_send)( sout_stream_t *, sout_stream_id_t *, sout_buffer_t* );
/* private */
sout_stream_sys_t *p_sys;
};
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;
char * psz_chain;
/* 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_stream_t *p_stream;
/* sout private */
sout_instance_sys_t *p_sys;
};
/* 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)--; \
} \
}
static inline sout_cfg_t *sout_cfg_find( sout_cfg_t *p_cfg, char *psz_name )
{
while( p_cfg && strcmp( p_cfg->psz_name, psz_name ) )
{
p_cfg = p_cfg->p_next;
}
return p_cfg;
}
static inline char *sout_cfg_find_value( sout_cfg_t *p_cfg, char *psz_name )
{
while( p_cfg && strcmp( p_cfg->psz_name, psz_name ) )
{
p_cfg = p_cfg->p_next;
}
if( p_cfg && p_cfg->psz_value )
{
return( p_cfg->psz_value );
}
return NULL;
}
/*****************************************************************************
* Prototypes
*****************************************************************************/
......@@ -227,7 +329,7 @@ VLC_EXPORT( sout_buffer_t *, sout_FifoShow, ( sout_fifo_t * ) );
#define sout_InputNew( a, b ) __sout_InputNew( VLC_OBJECT(a), b )
VLC_EXPORT( sout_packetizer_input_t *, __sout_InputNew, ( vlc_object_t *, sout_packet_format_t * ) );
VLC_EXPORT( sout_packetizer_input_t *, __sout_InputNew, ( vlc_object_t *, sout_format_t * ) );
VLC_EXPORT( int, sout_InputDelete, ( sout_packetizer_input_t * ) );
VLC_EXPORT( int, sout_InputSendBuffer, ( sout_packetizer_input_t *, sout_buffer_t* ) );
......@@ -243,3 +345,13 @@ VLC_EXPORT( void, sout_AccessOutDelete, ( sout_access_out_t * ) )
VLC_EXPORT( int, sout_AccessOutSeek, ( sout_access_out_t *, off_t ) );
VLC_EXPORT( int, sout_AccessOutWrite, ( sout_access_out_t *, sout_buffer_t * ) );
VLC_EXPORT( sout_mux_t *, sout_MuxNew, ( sout_instance_t*, char *, sout_access_out_t * ) );
VLC_EXPORT( sout_input_t *, sout_MuxAddStream, ( sout_mux_t *, sout_format_t * ) );
VLC_EXPORT( void, sout_MuxDeleteStream, ( sout_mux_t *, sout_input_t * ) );
VLC_EXPORT( void, sout_MuxDelete, ( sout_mux_t * ) );
VLC_EXPORT( void, sout_MuxSendBuffer, ( sout_mux_t *, sout_input_t *, sout_buffer_t * ) );
VLC_EXPORT( char *, sout_cfg_parser, ( char **, sout_cfg_t **, char * ) );
VLC_EXPORT( sout_stream_t *, sout_stream_new, ( sout_instance_t *, char *psz_chain ) );
VLC_EXPORT( void, sout_stream_delete, ( sout_stream_t *p_stream ) );
......@@ -3,7 +3,7 @@
* Collection of useful common types and macros definitions
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: vlc_common.h,v 1.59 2003/03/17 18:02:11 sam Exp $
* $Id: vlc_common.h,v 1.60 2003/04/13 20:00:20 fenrir Exp $
*
* Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr>
......@@ -249,11 +249,11 @@ typedef struct sout_fifo_t sout_fifo_t;
typedef struct sout_input_t sout_input_t;
typedef struct sout_packetizer_input_t sout_packetizer_input_t;
typedef struct sout_buffer_t sout_buffer_t;
typedef struct sout_packet_format_t sout_packet_format_t;
typedef struct sout_access_out_t sout_access_out_t;
typedef struct sout_mux_t sout_mux_t;
typedef struct sout_access_out_sys_t sout_access_out_sys_t;
typedef struct sout_stream_t sout_stream_t;
typedef struct sout_cfg_t sout_cfg_t;
typedef struct sout_format_t sout_format_t;
/* Decoders */
typedef struct decoder_fifo_t decoder_fifo_t;
......
......@@ -62,6 +62,7 @@ EXTRA_DIST = \
mux/Modules.am \
mux/mpeg/Modules.am \
packetizer/Modules.am \
stream_out/Modules.am \
video_chroma/Modules.am \
video_filter/Modules.am \
video_filter/deinterlace/Modules.am \
......
......@@ -2,7 +2,7 @@
* avi.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: avi.c,v 1.11 2003/03/31 03:46:11 fenrir Exp $
* $Id: avi.c,v 1.12 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -231,7 +231,7 @@ static void Close( vlc_object_t * p_this )
(uint64_t)p_stream->i_totalsize /
(uint64_t)p_stream->i_duration;
}
msg_Err( p_mux, "stream[%d] duration:%lld totalsize:%lld frames:%d fps:%f kb/s:%d",
msg_Info( p_mux, "stream[%d] duration:%lld totalsize:%lld frames:%d fps:%f kb/s:%d",
i_stream,
(int64_t)p_stream->i_duration / (int64_t)1000000,
p_stream->i_totalsize,
......@@ -266,11 +266,6 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
msg_Err( p_mux, "too many streams" );
return( -1 );
}
if( p_input->input_format.p_format == NULL )
{
msg_Err( p_mux, "stream descriptor missing" );
return( -1 );
}
msg_Dbg( p_mux, "adding input" );
p_input->p_sys = malloc( sizeof( int ) );
......@@ -278,13 +273,9 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
*((int*)p_input->p_sys) = p_sys->i_streams;
p_stream = &p_sys->stream[p_sys->i_streams];
switch( p_input->input_format.i_cat )
switch( p_input->p_fmt->i_cat )
{
case AUDIO_ES:
{
WAVEFORMATEX *p_wf =
(WAVEFORMATEX*)p_input->input_format.p_format;
p_stream->i_cat = AUDIO_ES;
p_stream->fcc[0] = '0' + p_sys->i_streams / 10;
p_stream->fcc[1] = '0' + p_sys->i_streams % 10;
......@@ -292,17 +283,45 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
p_stream->fcc[3] = 'b';
p_stream->p_bih = NULL;
p_stream->p_wf = malloc( sizeof( WAVEFORMATEX ) + p_wf->cbSize );
memcpy( p_stream->p_wf,
p_wf,
sizeof( WAVEFORMATEX ) + p_wf->cbSize);
p_stream->p_wf = malloc( sizeof( WAVEFORMATEX ) + p_input->p_fmt->i_extra_data );
#define p_wf p_stream->p_wf
p_wf->cbSize = p_input->p_fmt->i_extra_data;
if( p_wf->cbSize > 0 )
{
memcpy( &p_wf[1],
p_input->p_fmt->p_extra_data,
p_input->p_fmt->i_extra_data );
}
p_wf->nChannels = p_input->p_fmt->i_channels;
p_wf->nSamplesPerSec = p_input->p_fmt->i_sample_rate;
p_wf->nBlockAlign = p_input->p_fmt->i_block_align;
p_wf->nAvgBytesPerSec= p_input->p_fmt->i_bitrate / 8;
p_wf->wBitsPerSample = 0;
switch( p_input->p_fmt->i_fourcc )
{
case VLC_FOURCC( 'a', '5', '2', ' ' ):
p_wf->wFormatTag = WAVE_FORMAT_A52;
break;
case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
p_wf->wFormatTag = WAVE_FORMAT_MPEGLAYER3;
break;
case VLC_FOURCC( 'w', 'm', 'a', '1' ):
p_wf->wFormatTag = WAVE_FORMAT_WMA1;
break;
case VLC_FOURCC( 'w', 'm', 'a', '2' ):
p_wf->wFormatTag = WAVE_FORMAT_WMA2;
break;
case VLC_FOURCC( 'w', 'm', 'a', '3' ):
p_wf->wFormatTag = WAVE_FORMAT_WMA3;
break;
default:
return VLC_EGENERIC;
}
#undef p_wf
break;
case VIDEO_ES:
{
BITMAPINFOHEADER *p_bih =
(BITMAPINFOHEADER*)p_input->input_format.p_format;;
p_stream->i_cat = VIDEO_ES;
p_stream->fcc[0] = '0' + p_sys->i_streams / 10;
p_stream->fcc[1] = '0' + p_sys->i_streams % 10;
......@@ -313,14 +332,37 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
p_sys->i_stream_video = p_sys->i_streams;
}
p_stream->p_wf = NULL;
p_stream->p_bih = malloc( p_bih->biSize );
memcpy( p_stream->p_bih,
p_bih,
p_bih->biSize );
p_stream->p_bih = malloc( sizeof( BITMAPINFOHEADER ) + p_input->p_fmt->i_extra_data );
#define p_bih p_stream->p_bih
p_bih->biSize = sizeof( BITMAPINFOHEADER ) + p_input->p_fmt->i_extra_data;
if( p_input->p_fmt->i_extra_data > 0 )
{
memcpy( &p_bih[1],
p_input->p_fmt->p_extra_data,
p_input->p_fmt->i_extra_data );
}
p_bih->biWidth = p_input->p_fmt->i_width;
p_bih->biHeight= p_input->p_fmt->i_height;
p_bih->biPlanes= 1;
p_bih->biBitCount = 24;
p_bih->biSizeImage = 0;
p_bih->biXPelsPerMeter = 0;
p_bih->biYPelsPerMeter = 0;
p_bih->biClrUsed = 0;
p_bih->biClrImportant = 0;
switch( p_input->p_fmt->i_fourcc )
{
case VLC_FOURCC( 'm', 'p', '4', 'v' ):
p_bih->biCompression = VLC_FOURCC( 'X', 'V', 'I', 'D' );
break;
default:
p_bih->biCompression = p_input->p_fmt->i_fourcc;
break;
}
#undef p_bih
break;
default:
return( -1 );
return( VLC_EGENERIC );
}
p_stream->i_totalsize = 0;
p_stream->i_frames = 0;
......@@ -333,7 +375,7 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
p_sys->i_streams++;
return( 0 );
return( VLC_SUCCESS );
}
static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
......@@ -431,8 +473,8 @@ static int Mux ( sout_mux_t *p_mux )
p_data->i_size += 1;
}
sout_AccessOutWrite( p_mux->p_access, p_data );
p_sys->i_movi_size += p_data->i_size;
sout_AccessOutWrite( p_mux->p_access, p_data );
i_count--;
}
......@@ -649,7 +691,7 @@ static int avi_HeaderAdd_strh( sout_mux_t *p_mux,
if( i_samplesize > 1 )
{
i_scale = i_samplesize;
i_rate = i_scale * p_stream->i_bitrate / 8;
i_rate = /*i_scale **/ p_stream->i_bitrate / 8;
}
else
{
......
......@@ -2,7 +2,7 @@
* ps.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: ps.c,v 1.11 2003/03/11 19:02:30 fenrir Exp $
* $Id: ps.c,v 1.12 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
......@@ -174,11 +174,11 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
msg_Dbg( p_mux, "adding input" );
p_input->p_sys = (void*)p_stream = malloc( sizeof( ps_stream_t ) );
p_stream->i_ok = 0;
switch( p_input->input_format.i_cat )
switch( p_input->p_fmt->i_cat )
{
case VIDEO_ES:
switch( p_input->input_format.i_fourcc )
switch( p_input->p_fmt->i_fourcc )
{
case VLC_FOURCC( 'm', 'p', 'g', 'v' ):
p_stream->i_stream_id = p_sys->i_stream_id_mpgv;
......@@ -190,7 +190,7 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
}
break;
case AUDIO_ES:
switch( p_input->input_format.i_fourcc )
switch( p_input->p_fmt->i_fourcc )
{
case VLC_FOURCC( 'a', '5', '2', ' ' ):
case VLC_FOURCC( 'a', '5', '2', 'b' ):
......
......@@ -2,7 +2,7 @@
* ts.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: ts.c,v 1.15 2003/03/11 19:02:30 fenrir Exp $
* $Id: ts.c,v 1.16 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
......@@ -223,8 +223,6 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
{
sout_mux_sys_t *p_sys = p_mux->p_sys;
ts_stream_t *p_stream;
BITMAPINFOHEADER *p_bih;
WAVEFORMATEX *p_wf;
msg_Dbg( p_mux, "adding input" );
p_input->p_sys = (void*)p_stream = malloc( sizeof( ts_stream_t ) );
......@@ -236,10 +234,10 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
}
p_stream->i_continuity_counter = 0;
switch( p_input->input_format.i_cat )
switch( p_input->p_fmt->i_cat )
{
case VIDEO_ES:
switch( p_input->input_format.i_fourcc )
switch( p_input->p_fmt->i_fourcc )
{
case VLC_FOURCC( 'm', 'p','g', 'v' ):
p_stream->i_stream_type = 0x02;
......@@ -269,38 +267,28 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
return( -1 );
}
p_sys->i_video_bound++;
p_bih = (BITMAPINFOHEADER*)p_input->input_format.p_format;
if( p_bih )
{
p_stream->i_bih_codec = p_input->input_format.i_fourcc;
p_stream->i_bih_width = p_bih->biWidth;
p_stream->i_bih_height = p_bih->biHeight;
}
else
{
p_stream->i_bih_codec = 0x0;
p_stream->i_bih_width = 0;
p_stream->i_bih_height = 0;
}
if( p_bih && p_bih->biSize > sizeof( BITMAPINFOHEADER ) )
p_stream->i_bih_codec = p_input->p_fmt->i_fourcc;
p_stream->i_bih_width = p_input->p_fmt->i_width;
p_stream->i_bih_height = p_input->p_fmt->i_height;
p_stream->i_decoder_specific_info_len = p_input->p_fmt->i_extra_data;
if( p_stream->i_decoder_specific_info_len > 0 )
{
p_stream->i_decoder_specific_info_len =
p_bih->biSize - sizeof( BITMAPINFOHEADER );
p_stream->p_decoder_specific_info =
malloc( p_stream->i_decoder_specific_info_len );
memcpy( p_stream->p_decoder_specific_info,
&p_bih[1],
p_stream->i_decoder_specific_info_len );
p_input->p_fmt->p_extra_data,
p_input->p_fmt->i_extra_data );
}
else
{
p_stream->p_decoder_specific_info = NULL;
p_stream->i_decoder_specific_info_len = 0;
}
break;
case AUDIO_ES:
switch( p_input->input_format.i_fourcc )
switch( p_input->p_fmt->i_fourcc )
{
case VLC_FOURCC( 'a', '5','2', ' ' ):
case VLC_FOURCC( 'a', '5','2', 'b' ):
......@@ -324,20 +312,19 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
return( -1 );
}
p_sys->i_audio_bound++;
p_wf = (WAVEFORMATEX*)p_input->input_format.p_format;
if( p_wf && p_wf->cbSize > 0 )
p_stream->i_decoder_specific_info_len = p_input->p_fmt->i_extra_data;
if( p_stream->i_decoder_specific_info_len > 0 )
{
p_stream->i_decoder_specific_info_len = p_wf->cbSize;
p_stream->p_decoder_specific_info =
malloc( p_stream->i_decoder_specific_info_len );
memcpy( p_stream->p_decoder_specific_info,
&p_wf[1],
p_stream->i_decoder_specific_info_len );
p_input->p_fmt->p_extra_data,
p_input->p_fmt->i_extra_data );
}
else
{
p_stream->p_decoder_specific_info = NULL;
p_stream->i_decoder_specific_info_len = 0;
}
break;
default:
......
......@@ -2,7 +2,7 @@
* ogg.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: ogg.c,v 1.4 2003/03/31 03:46:11 fenrir Exp $
* $Id: ogg.c,v 1.5 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -209,33 +209,29 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
sout_mux_sys_t *p_sys = p_mux->p_sys;
ogg_stream_t *p_stream;
BITMAPINFOHEADER *p_bih;
WAVEFORMATEX *p_wf;
msg_Dbg( p_mux, "adding input" );
p_input->p_sys = (void*)p_stream = malloc( sizeof( ogg_stream_t ) );
p_stream->i_cat = p_input->input_format.i_cat;
p_stream->i_fourcc = p_input->input_format.i_fourcc;
p_stream->i_cat = p_input->p_fmt->i_cat;
p_stream->i_fourcc = p_input->p_fmt->i_fourcc;
p_stream->i_packet_no = 0;
p_stream->header.i_packet_type = PACKET_TYPE_HEADER;
switch( p_input->input_format.i_cat )
switch( p_input->p_fmt->i_cat )
{
case VIDEO_ES:
p_bih = (BITMAPINFOHEADER*)p_input->input_format.p_format;
switch( p_input->input_format.i_fourcc )
switch( p_input->p_fmt->i_fourcc )
{
case VLC_FOURCC( 'm', 'p','4', 'v' ):
case VLC_FOURCC( 'D', 'I','V', '3' ):
memcpy( p_stream->header.stream_type,
"video ",
8 );
if( p_input->input_format.i_fourcc == VLC_FOURCC( 'm', 'p','4', 'v' ) )
if( p_input->p_fmt->i_fourcc == VLC_FOURCC( 'm', 'p','4', 'v' ) )
{
memcpy( p_stream->header.sub_type, "XVID", 4 );
}
else if( p_input->input_format.i_fourcc == VLC_FOURCC( 'D', 'I','V', '3' ) )
else if( p_input->p_fmt->i_fourcc == VLC_FOURCC( 'D', 'I','V', '3' ) )
{
memcpy( p_stream->header.sub_type, "DIV3", 4 );
}
......@@ -246,16 +242,8 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
SetDWLE( &p_stream->header.i_default_len, 0 ); /* ??? */
SetDWLE( &p_stream->header.i_buffer_size, 1024*1024 );
SetWLE( &p_stream->header.i_bits_per_sample, 0 );
if( p_bih )
{
SetDWLE( &p_stream->header.header.video.i_width, p_bih->biWidth );
SetDWLE( &p_stream->header.header.video.i_height, p_bih->biHeight );
}
else
{
SetDWLE( &p_stream->header.header.video.i_width, 0 );
SetDWLE( &p_stream->header.header.video.i_height, 0 );
}
SetDWLE( &p_stream->header.header.video.i_width, p_input->p_fmt->i_width );
SetDWLE( &p_stream->header.header.video.i_height, p_input->p_fmt->i_height );
break;
default:
FREE( p_input->p_sys );
......@@ -263,19 +251,18 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
}
break;
case AUDIO_ES:
p_wf = (WAVEFORMATEX*)p_input->input_format.p_format;
switch( p_input->input_format.i_fourcc )
switch( p_input->p_fmt->i_fourcc )
{
case VLC_FOURCC( 'm', 'p','g', 'a' ):
case VLC_FOURCC( 'a', '5','2', ' ' ):
memcpy( p_stream->header.stream_type,
"audio ",
8 );
if( p_input->input_format.i_fourcc == VLC_FOURCC( 'm', 'p','g', 'a' ) )
if( p_input->p_fmt->i_fourcc == VLC_FOURCC( 'm', 'p','g', 'a' ) )
{
memcpy( p_stream->header.sub_type, "55 ", 4 );
}
else if( p_input->input_format.i_fourcc == VLC_FOURCC( 'a', '5','2', ' ' ) )
else if( p_input->p_fmt->i_fourcc == VLC_FOURCC( 'a', '5','2', ' ' ) )
{
memcpy( p_stream->header.sub_type, "2000", 4 );
}
......@@ -283,23 +270,11 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
SetQWLE( &p_stream->header.i_time_unit, 1000000 ); /* is it used ? */
SetDWLE( &p_stream->header.i_default_len, 0 ); /* ??? */
SetDWLE( &p_stream->header.i_buffer_size, 30*1024 );
if( p_wf )
{
SetQWLE( &p_stream->header.i_samples_per_unit, p_wf->nSamplesPerSec );
SetWLE( &p_stream->header.i_bits_per_sample, p_wf->wBitsPerSample );
SetDWLE( &p_stream->header.header.audio.i_channels, p_wf->nChannels );
SetDWLE( &p_stream->header.header.audio.i_block_align, p_wf->nBlockAlign );
SetDWLE( &p_stream->header.header.audio.i_avgbytespersec, p_wf->nAvgBytesPerSec );
}
else
{
/* perhaps it's better to fail */
SetQWLE( &p_stream->header.i_samples_per_unit, 44100 );
SetQWLE( &p_stream->header.i_samples_per_unit, p_input->p_fmt->i_sample_rate );
SetWLE( &p_stream->header.i_bits_per_sample, 0 );
SetDWLE( &p_stream->header.header.audio.i_channels, 2 );
SetDWLE( &p_stream->header.header.audio.i_block_align, 0 );
SetDWLE( &p_stream->header.header.audio.i_channels, p_input->p_fmt->i_channels );
SetDWLE( &p_stream->header.header.audio.i_block_align, p_input->p_fmt->i_block_align );
SetDWLE( &p_stream->header.header.audio.i_avgbytespersec, 0 );
}
break;
case VLC_FOURCC( 'v', 'o', 'r', 'b' ):
default:
......
......@@ -2,7 +2,7 @@
* a52.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: a52.c,v 1.3 2003/03/31 03:46:11 fenrir Exp $
* $Id: a52.c,v 1.4 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
......@@ -45,7 +45,7 @@ typedef struct packetizer_s
/* Output properties */
sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format;
sout_format_t output_format;
uint64_t i_samplescount;
......@@ -155,8 +155,6 @@ static int InitThread( packetizer_t *p_pack )
p_pack->output_format.i_cat = AUDIO_ES;
p_pack->output_format.i_fourcc = VLC_FOURCC( 'a', '5', '2', ' ' );
p_pack->output_format.p_format = NULL;
p_pack->p_sout_input = NULL;
p_pack->i_samplescount = 0;
......@@ -230,19 +228,12 @@ static void PacketizeThread( packetizer_t *p_pack )
if( !p_pack->p_sout_input )
{
/* add a input for the stream ouput */
WAVEFORMATEX *p_wf;
p_wf = malloc( sizeof( WAVEFORMATEX ) );
p_pack->output_format.p_format = (void*)p_wf;
p_wf->wFormatTag = WAVE_FORMAT_A52;
p_wf->nChannels = i_channels;
p_wf->nSamplesPerSec = i_samplerate;
p_wf->nAvgBytesPerSec = 0;
p_wf->nBlockAlign = 1;
p_wf->wBitsPerSample = 0;
p_wf->cbSize = 0;
p_pack->output_format.i_sample_rate = i_samplerate;
p_pack->output_format.i_channels = i_channels;
p_pack->output_format.i_block_align = 0;
p_pack->output_format.i_bitrate = 0;
p_pack->output_format.i_extra_data = 0;
p_pack->output_format.p_extra_data = NULL;
p_pack->p_sout_input =
sout_InputNew( p_pack->p_fifo,
......
......@@ -2,7 +2,7 @@
* copy.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: copy.c,v 1.6 2003/03/31 03:46:11 fenrir Exp $
* $Id: copy.c,v 1.7 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
......@@ -45,7 +45,7 @@ typedef struct packetizer_thread_s
/* Output properties */
sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format;
sout_format_t output_format;
// mtime_t i_last_pts;
......@@ -243,11 +243,26 @@ static int InitThread( packetizer_thread_t *p_pack )
p_pack->output_format.i_fourcc = VLC_FOURCC( 'd', 'v', 's', 'l' );
p_pack->output_format.i_cat = VIDEO_ES;
break;
case VLC_FOURCC( 'S', 'V', 'Q', '1' ):
p_pack->output_format.i_fourcc = VLC_FOURCC( 'S', 'V', 'Q', '1' );
p_pack->output_format.i_cat = VIDEO_ES;
break;
default:
p_pack->output_format.i_fourcc = p_pack->p_fifo->i_fourcc;
p_pack->output_format.i_cat = UNKNOWN_ES;
case VLC_FOURCC( 'w', 'm', 'a', '1' ):
p_pack->output_format.i_fourcc = VLC_FOURCC( 'w', 'm', 'a', '1' );
p_pack->output_format.i_cat = AUDIO_ES;
break;
case VLC_FOURCC( 'w', 'm', 'a', '2' ):
p_pack->output_format.i_fourcc = VLC_FOURCC( 'w', 'm', 'a', '2' );
p_pack->output_format.i_cat = AUDIO_ES;
break;
default:
msg_Err( p_pack->p_fifo, "unknown es type !!" );
return VLC_EGENERIC;
//p_pack->output_format.i_fourcc = p_pack->p_fifo->i_fourcc;
//p_pack->output_format.i_cat = UNKNOWN_ES;
//break;
}
switch( p_pack->output_format.i_cat )
......@@ -257,12 +272,32 @@ static int InitThread( packetizer_thread_t *p_pack )
WAVEFORMATEX *p_wf = (WAVEFORMATEX*)p_pack->p_fifo->p_waveformatex;
if( p_wf )
{
p_pack->output_format.p_format = malloc( sizeof( WAVEFORMATEX ) + p_wf->cbSize );
memcpy( p_pack->output_format.p_format, p_wf, sizeof( WAVEFORMATEX ) + p_wf->cbSize );
p_pack->output_format.i_sample_rate = p_wf->nSamplesPerSec;
p_pack->output_format.i_channels = p_wf->nChannels;
p_pack->output_format.i_block_align = p_wf->nBlockAlign;
p_pack->output_format.i_bitrate = p_wf->nAvgBytesPerSec * 8;
p_pack->output_format.i_extra_data = p_wf->cbSize;
if( p_wf->cbSize > 0 )
{
p_pack->output_format.p_extra_data =
malloc( p_pack->output_format.i_extra_data );
memcpy( p_pack->output_format.p_extra_data,
&p_wf[1],
p_pack->output_format.i_extra_data );
}
else
{
p_pack->output_format.p_extra_data = NULL;
}
}
else
{
p_pack->output_format.p_format = NULL;
p_pack->output_format.i_sample_rate = 0;
p_pack->output_format.i_channels = 0;
p_pack->output_format.i_block_align = 0;
p_pack->output_format.i_bitrate = 0;
p_pack->output_format.i_extra_data = 0;
p_pack->output_format.p_extra_data = NULL;
}
}
break;
......@@ -270,29 +305,34 @@ static int InitThread( packetizer_thread_t *p_pack )
case VIDEO_ES:
{
BITMAPINFOHEADER *p_bih = (BITMAPINFOHEADER*)p_pack->p_fifo->p_bitmapinfoheader;
p_pack->output_format.i_bitrate = 0;
if( p_bih )
{
p_pack->output_format.p_format = malloc( p_bih->biSize );
memcpy( p_pack->output_format.p_format, p_bih, p_bih->biSize );
if( p_pack->output_format.i_fourcc == VLC_FOURCC( 'm', 'p', '4', 'v' ) )
p_pack->output_format.i_width = p_bih->biWidth;
p_pack->output_format.i_height = p_bih->biHeight;
p_pack->output_format.i_extra_data = p_bih->biSize - sizeof( BITMAPINFOHEADER );
if( p_pack->output_format.i_extra_data > 0 )
{
p_bih->biCompression = VLC_FOURCC( 'd', 'i', 'v', 'x' );
p_pack->output_format.p_extra_data =
malloc( p_pack->output_format.i_extra_data );
memcpy( p_pack->output_format.p_extra_data,
&p_bih[1],
p_pack->output_format.i_extra_data );
}
else
{
p_bih->biCompression = p_pack->output_format.i_fourcc;
}
}
else
{
p_pack->output_format.p_format = NULL;
p_pack->output_format.i_width = 0;
p_pack->output_format.i_height = 0;
p_pack->output_format.i_extra_data = 0;
p_pack->output_format.p_extra_data = NULL;
}
}
break;
default:
p_pack->output_format.p_format = NULL;
break;
return VLC_EGENERIC;
}
p_pack->p_sout_input =
......@@ -302,10 +342,10 @@ static int InitThread( packetizer_thread_t *p_pack )
if( !p_pack->p_sout_input )
{
msg_Err( p_pack->p_fifo, "cannot add a new stream" );
return( -1 );
return VLC_EGENERIC;
}
// p_pack->i_last_pts = 0;
return( 0 );
return( VLC_SUCCESS );
}
/*****************************************************************************
......@@ -329,7 +369,7 @@ static void PacketizeThread( packetizer_thread_t *p_pack )
if( i_pts <= 0 ) //&& p_pack->i_last_pts <= 0 )
{
msg_Err( p_pack->p_fifo, "need pts != 0" );
msg_Dbg( p_pack->p_fifo, "need pts != 0" );
input_DeletePES( p_pack->p_fifo->p_packets_mgt, p_pes );
return;
}
......
......@@ -2,7 +2,7 @@
* mpeg4audio.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: mpeg4audio.c,v 1.4 2003/03/31 03:46:11 fenrir Exp $
* $Id: mpeg4audio.c,v 1.5 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -60,7 +60,7 @@ typedef struct packetizer_thread_s
/* Output properties */
sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format;
sout_format_t output_format;
// mtime_t i_pts_start;
mtime_t i_last_pts;
......@@ -187,17 +187,8 @@ static int InitThread( packetizer_thread_t *p_pack )
if( p_wf && p_wf->cbSize > 0)
{
uint8_t *p_config = (uint8_t*)&p_wf[1];
int i_wf = sizeof( WAVEFORMATEX ) + p_wf->cbSize;
int i_index;
p_pack->p_wf = malloc( i_wf );
memcpy( p_pack->p_wf,
p_wf,
i_wf );
p_pack->output_format.i_cat = AUDIO_ES;
p_pack->output_format.i_fourcc = VLC_FOURCC( 'm', 'p', '4', 'a' );
p_pack->output_format.p_format = p_pack->p_wf;
p_pack->b_adts = 0;
i_index = ( ( p_config[0] << 1 ) | ( p_config[1] >> 7 ) )&0x0f;
......@@ -216,6 +207,19 @@ static int InitThread( packetizer_thread_t *p_pack )
"aac %dHz %d samples/frame",
p_pack->i_sample_rate,
p_pack->i_frame_size );
p_pack->output_format.i_cat = AUDIO_ES;
p_pack->output_format.i_fourcc = VLC_FOURCC( 'm', 'p', '4', 'a' );
p_pack->output_format.i_sample_rate = p_pack->i_sample_rate;
p_pack->output_format.i_channels = p_wf->nChannels;
p_pack->output_format.i_block_align = 0;
p_pack->output_format.i_bitrate = 0;
p_pack->output_format.i_extra_data = p_wf->cbSize;
p_pack->output_format.p_extra_data = malloc( p_wf->cbSize );
memcpy( p_pack->output_format.p_extra_data,
&p_wf[1],
p_wf->cbSize );
}
else
{
......
......@@ -2,7 +2,7 @@
* mpeg4video.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: mpeg4video.c,v 1.9 2003/03/31 03:46:11 fenrir Exp $
* $Id: mpeg4video.c,v 1.10 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
......@@ -46,7 +46,7 @@ typedef struct packetizer_thread_s
/* Output properties */
sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format;
sout_format_t output_format;
mtime_t i_last_pts;
......@@ -198,8 +198,15 @@ static int InitThread( packetizer_thread_t *p_pack )
/* create stream input output */
p_pack->output_format.i_cat = VIDEO_ES;
p_pack->output_format.i_fourcc = VLC_FOURCC( 'm', 'p', '4', 'v' );
p_pack->output_format.p_format = malloc( p_bih->biSize );
memcpy( p_pack->output_format.p_format, p_bih, p_bih->biSize );
p_pack->output_format.i_width = p_bih->biWidth;
p_pack->output_format.i_height = p_bih->biHeight;
p_pack->output_format.i_bitrate= 0;
p_pack->output_format.i_extra_data = p_pack->i_vol;
p_pack->output_format.p_extra_data = malloc( p_pack->i_vol );
memcpy( p_pack->output_format.p_extra_data,
p_pack->p_vol,
p_pack->i_vol );
msg_Warn( p_pack->p_fifo, "opening with vol size:%d", p_pack->i_vol );
p_pack->p_sout_input =
......@@ -212,7 +219,11 @@ static int InitThread( packetizer_thread_t *p_pack )
p_pack->p_vol = 0;
p_pack->output_format.i_cat = UNKNOWN_ES;
p_pack->output_format.i_fourcc = VLC_FOURCC( 'n', 'u', 'l', 'l' );
p_pack->output_format.p_format = NULL;
p_pack->output_format.i_width = 0;
p_pack->output_format.i_height = 0;
p_pack->output_format.i_bitrate= 0;
p_pack->output_format.i_extra_data = 0;
p_pack->output_format.p_extra_data = NULL;
p_pack->p_sout_input =
sout_InputNew( p_pack->p_fifo,
......@@ -260,12 +271,14 @@ static void PacketizeThread( packetizer_thread_t *p_pack )
}
i_pts = p_pes->i_pts;
#if 0
if( i_pts <= 0 && p_pack->i_last_pts <= 0 )
{
msg_Err( p_pack->p_fifo, "need a starting pts" );
msg_Dbg( p_pack->p_fifo, "need a starting pts" );
input_DeletePES( p_pack->p_fifo->p_packets_mgt, p_pes );
return;
}
#endif
i_size = p_pes->i_pes_size;
if( i_size > 0 )
......@@ -364,8 +377,6 @@ static void PacketizeThread( packetizer_thread_t *p_pack )
if( p_vol_end != NULL && p_vol_begin < p_vol_end )
{
BITMAPINFOHEADER *p_bih;
p_pack->i_vol = p_vol_end - p_vol_begin;
msg_Dbg( p_pack->p_fifo, "Reopening output" );
......@@ -376,21 +387,16 @@ static void PacketizeThread( packetizer_thread_t *p_pack )
p_pack->output_format.i_cat = VIDEO_ES;
p_pack->output_format.i_fourcc = VLC_FOURCC( 'm', 'p', '4', 'v' );
p_pack->output_format.p_format =
(void*)p_bih = malloc( sizeof( BITMAPINFOHEADER ) + p_pack->i_vol);
p_bih->biSize = sizeof( BITMAPINFOHEADER ) + p_pack->i_vol;
p_bih->biWidth = 0;
p_bih->biHeight = 0;
p_bih->biPlanes = 1;
p_bih->biBitCount = 24;
p_bih->biCompression = VLC_FOURCC( 'd', 'i', 'v', 'x' );
p_bih->biSizeImage = 0;
p_bih->biXPelsPerMeter = 0;
p_bih->biYPelsPerMeter = 0;
p_bih->biClrUsed = 0;
p_bih->biClrImportant = 0;
memcpy( &p_bih[1], p_pack->p_vol, p_pack->i_vol );
p_pack->output_format.i_width = 0;
p_pack->output_format.i_height = 0;
p_pack->output_format.i_bitrate= 0;
p_pack->output_format.i_extra_data = p_pack->i_vol;
p_pack->output_format.p_extra_data = malloc( p_pack->i_vol );
memcpy( p_pack->output_format.p_extra_data,
p_pack->p_vol,
p_pack->i_vol );
p_pack->p_sout_input =
sout_InputNew( p_pack->p_fifo,
......@@ -410,9 +416,17 @@ static void PacketizeThread( packetizer_thread_t *p_pack )
}
}
if( i_pts > 0 )
{
sout_InputSendBuffer( p_pack->p_sout_input,
p_sout_buffer );
}
else
{
sout_BufferDelete( p_pack->p_sout_input->p_sout,
p_sout_buffer );
}
}
input_DeletePES( p_pack->p_fifo->p_packets_mgt, p_pes );
}
......
......@@ -2,7 +2,7 @@
* mpegaudio.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: mpegaudio.c,v 1.5 2003/03/31 03:46:11 fenrir Exp $
* $Id: mpegaudio.c,v 1.6 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
......@@ -45,7 +45,7 @@ typedef struct packetizer_s
/* Output properties */
sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format;
sout_format_t output_format;
uint64_t i_samplescount;
uint32_t i_samplespersecond;
......@@ -180,8 +180,13 @@ static int InitThread( packetizer_t *p_pack )
p_pack->output_format.i_cat = AUDIO_ES;
p_pack->output_format.i_fourcc = p_pack->p_fifo->i_fourcc;
p_pack->output_format.i_sample_rate = 0;
p_pack->output_format.i_channels = 0;
p_pack->output_format.i_block_align = 0;
p_pack->output_format.i_bitrate = 0;
p_pack->output_format.i_extra_data = 0;
p_pack->output_format.p_extra_data = NULL;
p_pack->output_format.p_format = NULL;
p_pack->p_sout_input = NULL;
......@@ -301,18 +306,10 @@ static void PacketizeThread( packetizer_t *p_pack )
if( !p_pack->p_sout_input )
{
/* add a input for the stream ouput */
WAVEFORMATEX *p_wf;
p_wf = malloc( sizeof( WAVEFORMATEX ) );
p_pack->output_format.p_format = (void*)p_wf;
p_wf->wFormatTag = WAVE_FORMAT_MPEG;
p_wf->nChannels = i_channels;
p_wf->nSamplesPerSec = i_samplerate;
p_wf->nAvgBytesPerSec = 0;
p_wf->nBlockAlign = 1;
p_wf->wBitsPerSample = 0;
p_wf->cbSize = 0; // FIXME there are more field for mpegaudio
p_pack->output_format.i_sample_rate = i_samplerate;
p_pack->output_format.i_channels = i_channels;
p_pack->output_format.i_block_align = 1;
p_pack->output_format.i_bitrate = 0;
p_pack->p_sout_input =
sout_InputNew( p_pack->p_fifo,
......
......@@ -2,7 +2,7 @@
* mpegvideo.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: mpegvideo.c,v 1.11 2003/03/31 03:46:11 fenrir Exp $
* $Id: mpegvideo.c,v 1.12 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org>
......@@ -45,7 +45,7 @@ typedef struct packetizer_s
/* Output properties */
sout_packetizer_input_t *p_sout_input;
sout_packet_format_t output_format;
sout_format_t output_format;
mtime_t i_last_dts;
mtime_t i_last_ref_pts;
......@@ -157,6 +157,11 @@ static int InitThread( packetizer_t *p_pack )
p_pack->output_format.i_cat = VIDEO_ES;
p_pack->output_format.i_fourcc = VLC_FOURCC( 'm', 'p', 'g', 'v');
p_pack->output_format.i_width = 0;
p_pack->output_format.i_height = 0;
p_pack->output_format.i_bitrate= 0;
p_pack->output_format.i_extra_data = 0;
p_pack->output_format.p_extra_data = NULL;
p_pack->p_sout_input = NULL;
......@@ -228,10 +233,7 @@ static void PacketizeThread( packetizer_t *p_pack )
byte_t p_temp[512];/* 150 bytes is the maximal size
of a sequence_header + sequence_extension */
int i_frame_rate_code;
BITMAPINFOHEADER *p_bih;
p_bih = malloc( sizeof( BITMAPINFOHEADER ) );
p_pack->output_format.p_format = (void*)p_bih;
/* skip data until we find a sequence_header_code */
/* TODO: store skipped somewhere so can send it to the mux
......@@ -250,21 +252,12 @@ static void PacketizeThread( packetizer_t *p_pack )
i_pos = 0;
GetChunk( &p_pack->bit_stream, p_temp, 4 ); i_pos += 4;
p_bih->biSize = sizeof( BITMAPINFOHEADER );
/* horizontal_size_value */
p_bih->biWidth = ShowBits( &p_pack->bit_stream, 12 );
p_pack->output_format.i_width = ShowBits( &p_pack->bit_stream, 12 );
/* vertical_size_value */
p_bih->biHeight = ShowBits( &p_pack->bit_stream, 24 ) & 0xFFF;
p_pack->output_format.i_height= ShowBits( &p_pack->bit_stream, 24 ) & 0xFFF;
/* frame_rate_code */
i_frame_rate_code = ShowBits( &p_pack->bit_stream, 32 ) & 0xF;
p_bih->biPlanes = 1;
p_bih->biBitCount = 0;
p_bih->biCompression = VLC_FOURCC( 'm', 'p', 'g', '2' );
p_bih->biSizeImage = 0;
p_bih->biXPelsPerMeter = 0;
p_bih->biYPelsPerMeter = 0;
p_bih->biClrUsed = 0;
p_bih->biClrImportant = 0;
/* copy headers */
GetChunk( &p_pack->bit_stream, p_temp + i_pos, 7 ); i_pos += 7;
......@@ -313,7 +306,9 @@ static void PacketizeThread( packetizer_t *p_pack )
msg_Warn( p_pack->p_fifo,
"creating input (image size %dx%d, frame rate %.2f)",
p_bih->biWidth, p_bih->biHeight, p_pack->d_frame_rate );
p_pack->output_format.i_width,
p_pack->output_format.i_height,
p_pack->d_frame_rate );
/* now we have informations to create the input */
p_pack->p_sout_input = sout_InputNew( p_pack->p_fifo,
......@@ -365,7 +360,8 @@ static void PacketizeThread( packetizer_t *p_pack )
}
p_pack->i_last_ref_pts =
p_pack->i_last_dts + 40000; /* FIXME */
p_pack->i_last_dts +
(mtime_t)( 1000000 / p_pack->d_frame_rate); /* FIXME */
CopyUntilNextStartCode( p_pack, p_sout_buffer, &i_pos );
}
else if( i_code == 0x100 ) /* Picture */
......@@ -437,16 +433,21 @@ static void PacketizeThread( packetizer_t *p_pack )
return;
}
#if 1
if( i_dts > 0 )
{
//if( i_dts - p_pack->i_last_dts > 200000 ||
// i_dts - p_pack->i_last_dts < 200000 )
{
p_pack->i_last_dts = i_dts;
}
if( i_pts > 0 )
{
p_pack->i_last_ref_pts =
i_pts - i_temporal_ref *
(mtime_t)( 1000000 / p_pack->d_frame_rate );
p_pack->i_last_ref_pts = i_pts -
i_temporal_ref * (mtime_t)( 1000000 / p_pack->d_frame_rate );
}
}
}
#endif
p_sout_buffer->i_dts = p_pack->i_last_dts;
p_sout_buffer->i_pts = p_pack->i_last_ref_pts +
......
SOURCES_stream_out_dummy = modules/stream_out/dummy.c
SOURCES_stream_out_standard = modules/stream_out/standard.c
SOURCES_stream_out_transcode = modules/stream_out/transcode.c
SOURCES_stream_out_duplicate = modules/stream_out/duplicate.c
SOURCES_stream_out_es = modules/stream_out/es.c
SOURCES_stream_out_display = modules/stream_out/display.c
/*****************************************************************************
* display.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: display.c,v 1.1 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include <vlc/vlc.h>
#include <vlc/input.h>
#include <vlc/sout.h>
#include "codecs.h"
/*****************************************************************************
* Exported prototypes
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static sout_stream_id_t *Add ( sout_stream_t *, sout_format_t * );
static int Del ( sout_stream_t *, sout_stream_id_t * );
static int Send( sout_stream_t *, sout_stream_id_t *, sout_buffer_t* );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("Display stream") );
set_capability( "sout stream", 50 );
add_shortcut( "display" );
set_callbacks( Open, Close );
vlc_module_end();
struct sout_stream_sys_t
{
input_thread_t *p_input;
vlc_bool_t b_audio;
vlc_bool_t b_video;
mtime_t i_delay;
};
/*****************************************************************************
* Open:
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
sout_stream_t *p_stream = (sout_stream_t*)p_this;
sout_stream_sys_t *p_sys;
char *val;
p_sys = malloc( sizeof( sout_stream_sys_t ) );
p_sys->p_input = vlc_object_find( p_stream, VLC_OBJECT_INPUT, FIND_ANYWHERE );
if( !p_sys->p_input )
{
msg_Err( p_stream, "cannot find p_input" );
free( p_sys );
return VLC_EGENERIC;
}
p_sys->b_audio = VLC_TRUE;
p_sys->b_video = VLC_TRUE;
p_sys->i_delay = 100*1000;
if( sout_cfg_find( p_stream->p_cfg, "noaudio" ) )
{
p_sys->b_audio = VLC_FALSE;
}
if( sout_cfg_find( p_stream->p_cfg, "novideo" ) )
{
p_sys->b_video = VLC_FALSE;
}
if( ( val = sout_cfg_find_value( p_stream->p_cfg, "delay" ) ) )
{
p_sys->i_delay = (mtime_t)atoi( val ) * (mtime_t)1000;
}
p_stream->pf_add = Add;
p_stream->pf_del = Del;
p_stream->pf_send = Send;
p_stream->p_sys = p_sys;
return VLC_SUCCESS;
}
/*****************************************************************************
* Close:
*****************************************************************************/
static void Close( vlc_object_t * p_this )
{
sout_stream_t *p_stream = (sout_stream_t*)p_this;
sout_stream_sys_t *p_sys = p_stream->p_sys;
vlc_object_release( p_sys->p_input );
free( p_sys );
}
struct sout_stream_id_t
{
es_descriptor_t *p_es;
};
static sout_stream_id_t * Add ( sout_stream_t *p_stream, sout_format_t *p_fmt )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
sout_stream_id_t *id;
if( ( p_fmt->i_cat == AUDIO_ES && !p_sys->b_audio )||
( p_fmt->i_cat == VIDEO_ES && !p_sys->b_video ) )
{
return NULL;
}
id = malloc( sizeof( sout_stream_id_t ) );
vlc_mutex_lock( &p_sys->p_input->stream.stream_lock );
id->p_es = input_AddES( p_sys->p_input,
NULL, /* no program */
12, /* es_id */
0 ); /* no extra data */
if( !id->p_es )
{
vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
msg_Err( p_stream, "cannot create es" );
free( id );
return NULL;
}
id->p_es->i_stream_id = 1;
id->p_es->i_cat = UNKNOWN_ES; //p_fmt->i_cat;
id->p_es->i_fourcc = p_fmt->i_fourcc;
id->p_es->b_force_decoder = VLC_TRUE;
switch( p_fmt->i_cat )
{
case AUDIO_ES:
id->p_es->p_bitmapinfoheader = NULL;
id->p_es->p_waveformatex =
malloc( sizeof( WAVEFORMATEX ) + p_fmt->i_extra_data );
#define p_wf ((WAVEFORMATEX*)id->p_es->p_waveformatex)
p_wf->wFormatTag = WAVE_FORMAT_UNKNOWN;
p_wf->nChannels = p_fmt->i_channels;
p_wf->nSamplesPerSec = p_fmt->i_sample_rate;
p_wf->nAvgBytesPerSec= p_fmt->i_bitrate / 8;
p_wf->nBlockAlign = p_fmt->i_block_align;
p_wf->wBitsPerSample = 0;
p_wf->cbSize = p_fmt->i_extra_data;
if( p_fmt->i_extra_data > 0 )
{
memcpy( &p_wf[1],
p_fmt->p_extra_data,
p_fmt->i_extra_data );
}
#undef p_wf
break;
case VIDEO_ES:
id->p_es->p_waveformatex = NULL;
id->p_es->p_bitmapinfoheader = malloc( sizeof( BITMAPINFOHEADER ) + p_fmt->i_extra_data );
#define p_bih ((BITMAPINFOHEADER*)id->p_es->p_bitmapinfoheader)
p_bih->biSize = sizeof( BITMAPINFOHEADER ) + p_fmt->i_extra_data;
p_bih->biWidth = p_fmt->i_width;
p_bih->biHeight = p_fmt->i_height;
p_bih->biPlanes = 0;
p_bih->biBitCount = 0;
p_bih->biCompression = 0;
p_bih->biSizeImage = 0;
p_bih->biXPelsPerMeter = 0;
p_bih->biYPelsPerMeter = 0;
p_bih->biClrUsed = 0;
p_bih->biClrImportant = 0;
if( p_fmt->i_extra_data > 0 )
{
memcpy( &p_bih[1],
p_fmt->p_extra_data,
p_fmt->i_extra_data );
}
#undef p_bih
break;
default:
msg_Err( p_stream, "unknown es type" );
free( id );
return NULL;
}
if( input_SelectES( p_sys->p_input, id->p_es ) )
{
input_DelES( p_sys->p_input, id->p_es );
vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
msg_Err( p_stream, "cannot select es" );
free( id );
return NULL;
}
vlc_mutex_unlock( &p_sys->p_input->stream.stream_lock );
return id;
}
static int Del ( sout_stream_t *p_stream, sout_stream_id_t *id )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
input_DelES( p_sys->p_input, id->p_es );
free( id );
return VLC_SUCCESS;
}
static int Send ( sout_stream_t *p_stream, sout_stream_id_t *id, sout_buffer_t *p_buffer )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
while( p_buffer )
{
sout_buffer_t *p_next;
pes_packet_t *p_pes;
data_packet_t *p_data;
if( p_buffer->i_size > 0 )
{
if( !( p_pes = input_NewPES( p_sys->p_input->p_method_data ) ) )
{
msg_Err( p_stream, "cannot allocate new PES" );
return VLC_EGENERIC;
}
if( !( p_data = input_NewPacket( p_sys->p_input->p_method_data, p_buffer->i_size ) ) )
{
msg_Err( p_stream, "cannot allocate new data_packet" );
return VLC_EGENERIC;
}
p_pes->i_dts = p_buffer->i_dts + p_sys->i_delay;
p_pes->i_pts = p_buffer->i_pts + p_sys->i_delay;
p_pes->p_first = p_pes->p_last = p_data;
p_pes->i_nb_data = 1;
p_pes->i_pes_size = p_buffer->i_size;
p_stream->p_vlc->pf_memcpy( p_data->p_payload_start,
p_buffer->p_buffer,
p_buffer->i_size );
if( id->p_es->p_decoder_fifo )
{
input_DecodePES( id->p_es->p_decoder_fifo, p_pes );
}
else
{
input_DeletePES( p_sys->p_input->p_method_data, p_pes );
}
}
/* *** go to next buffer *** */
p_next = p_buffer->p_next;
sout_BufferDelete( p_stream->p_sout, p_buffer );
p_buffer = p_next;
}
return VLC_SUCCESS;
}
/*****************************************************************************
* dummy.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: dummy.c,v 1.1 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include <vlc/vlc.h>
#include <vlc/sout.h>
/*****************************************************************************
* Exported prototypes
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static sout_stream_id_t *Add ( sout_stream_t *, sout_format_t * );
static int Del ( sout_stream_t *, sout_stream_id_t * );
static int Send( sout_stream_t *, sout_stream_id_t *, sout_buffer_t* );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("Dummy stream") );
set_capability( "sout stream", 50 );
add_shortcut( "dummy" );
set_callbacks( Open, Close );
vlc_module_end();
/*****************************************************************************
* Open:
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
sout_stream_t *p_stream = (sout_stream_t*)p_this;
p_stream->pf_add = Add;
p_stream->pf_del = Del;
p_stream->pf_send = Send;
p_stream->p_sys = NULL;
return VLC_SUCCESS;
}
/*****************************************************************************
* Close:
*****************************************************************************/
static void Close( vlc_object_t * p_this )
{
sout_stream_t *p_stream = (sout_stream_t*)p_this;
}
struct sout_stream_id_t
{
int i_d_u_m_m_y;
};
static sout_stream_id_t * Add ( sout_stream_t *p_stream, sout_format_t *p_fmt )
{
sout_stream_id_t *id;
id = malloc( sizeof( sout_stream_id_t ) );
id->i_d_u_m_m_y = 0;
return id;
}
static int Del ( sout_stream_t *p_stream, sout_stream_id_t *id )
{
free( id );
return VLC_SUCCESS;
}
static int Send ( sout_stream_t *p_stream, sout_stream_id_t *id, sout_buffer_t *p_buffer )
{
sout_buffer_t *p_next;
while( p_buffer )
{
p_next = p_buffer->p_next;
sout_BufferDelete( p_stream->p_sout, p_buffer );
p_buffer = p_next;
}
return VLC_SUCCESS;
}
/*****************************************************************************
* duplicate.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: duplicate.c,v 1.1 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include <vlc/vlc.h>
#include <vlc/sout.h>
/*****************************************************************************
* Exported prototypes
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static sout_stream_id_t *Add ( sout_stream_t *, sout_format_t * );
static int Del ( sout_stream_t *, sout_stream_id_t * );
static int Send( sout_stream_t *, sout_stream_id_t *, sout_buffer_t* );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("Duplicate stream") );
set_capability( "sout stream", 50 );
add_shortcut( "duplicate" );
add_shortcut( "dup" );
set_callbacks( Open, Close );
vlc_module_end();
struct sout_stream_sys_t
{
int i_nb_streams;
sout_stream_t **pp_streams;
};
struct sout_stream_id_t
{
int i_nb_ids;
void **pp_ids;
};
/*****************************************************************************
* Open:
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
sout_stream_t *p_stream = (sout_stream_t*)p_this;
sout_stream_sys_t *p_sys;
sout_cfg_t *p_cfg;
msg_Dbg( p_stream, "creating a duplication" );
p_sys = malloc( sizeof( sout_stream_sys_t ) );
p_sys->i_nb_streams = 0;
p_sys->pp_streams = NULL;
for( p_cfg = p_stream->p_cfg; p_cfg != NULL; p_cfg = p_cfg->p_next )
{
if( !strncmp( p_cfg->psz_name, "dst", strlen( "dst" ) ) )
{
sout_stream_t *s;
msg_Dbg( p_stream, " * adding `%s'", p_cfg->psz_value );
s = sout_stream_new( p_stream->p_sout, p_cfg->psz_value );
TAB_APPEND( p_sys->i_nb_streams, p_sys->pp_streams, s );
}
}
if( p_sys->i_nb_streams == 0 )
{
msg_Err( p_stream, "no destination given" );
free( p_sys );
return VLC_EGENERIC;
}
p_stream->pf_add = Add;
p_stream->pf_del = Del;
p_stream->pf_send = Send;
p_stream->p_sys = p_sys;
return VLC_SUCCESS;
}
/*****************************************************************************
* Close:
*****************************************************************************/
static void Close( vlc_object_t * p_this )
{
sout_stream_t *p_stream = (sout_stream_t*)p_this;
sout_stream_sys_t *p_sys = p_stream->p_sys;
int i;
msg_Dbg( p_stream, "closing a duplication" );
for( i = 0; i < p_sys->i_nb_streams; i++ )
{
sout_stream_delete( p_sys->pp_streams[i] );
}
free( p_sys->pp_streams );
free( p_sys );
}
static sout_stream_id_t * Add ( sout_stream_t *p_stream, sout_format_t *p_fmt )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
sout_stream_id_t *id;
int i_stream;
id = malloc( sizeof( sout_stream_id_t ) );
id->i_nb_ids = 0;
id->pp_ids = NULL;
for( i_stream = 0; i_stream < p_sys->i_nb_streams; i_stream++ )
{
void *id_new;
/* XXX not the same sout_stream_id_t definition ... */
id_new = (void*)p_sys->pp_streams[i_stream]->pf_add( p_sys->pp_streams[i_stream], p_fmt );
TAB_APPEND( id->i_nb_ids, id->pp_ids, id_new );
}
if( id->i_nb_ids <= 0 )
{
free( id );
return NULL;
}
return id;
}
static int Del ( sout_stream_t *p_stream, sout_stream_id_t *id )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
int i_stream;
for( i_stream = 0; i_stream < p_sys->i_nb_streams; i_stream++ )
{
if( id->pp_ids[i_stream] )
{
p_sys->pp_streams[i_stream]->pf_del( p_sys->pp_streams[i_stream],
id->pp_ids[i_stream] );
}
}
free( id->pp_ids );
free( id );
return VLC_SUCCESS;
}
static int Send ( sout_stream_t *p_stream, sout_stream_id_t *id, sout_buffer_t *p_buffer )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
int i_stream;
for( i_stream = 0; i_stream < p_sys->i_nb_streams - 1; i_stream++ )
{
sout_buffer_t *p_dup;
if( id->pp_ids[i_stream] )
{
p_dup = sout_BufferDuplicate( p_stream->p_sout, p_buffer );
p_sys->pp_streams[i_stream]->pf_send( p_sys->pp_streams[i_stream],
id->pp_ids[i_stream],
p_dup );
}
}
i_stream = p_sys->i_nb_streams - 1;
if( id->pp_ids[i_stream] )
{
p_sys->pp_streams[i_stream]->pf_send( p_sys->pp_streams[i_stream],
id->pp_ids[i_stream],
p_buffer);
}
return VLC_SUCCESS;
}
/*****************************************************************************
* es.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: es.c,v 1.1 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include <vlc/vlc.h>
#include <vlc/input.h>
#include <vlc/sout.h>
#define FREE( p ) if( p ) { free( p ); (p) = NULL; }
/*****************************************************************************
* Exported prototypes
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static sout_stream_id_t *Add ( sout_stream_t *, sout_format_t * );
static int Del ( sout_stream_t *, sout_stream_id_t * );
static int Send( sout_stream_t *, sout_stream_id_t *, sout_buffer_t* );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("ES stream") );
set_capability( "sout stream", 50 );
add_shortcut( "es" );
add_shortcut( "es" );
set_callbacks( Open, Close );
vlc_module_end();
struct sout_stream_sys_t
{
int i_count_audio;
int i_count_video;
int i_count;
char *psz_mux;
char *psz_mux_audio;
char *psz_mux_video;
char *psz_access;
char *psz_access_audio;
char *psz_access_video;
char *psz_url;
char *psz_url_audio;
char *psz_url_video;
};
/*****************************************************************************
* Open:
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
sout_stream_t *p_stream = (sout_stream_t*)p_this;
sout_stream_sys_t *p_sys;
//p_sout->i_preheader = __MAX( p_sout->i_preheader, p_mux->i_preheader );
p_sys = malloc( sizeof( sout_stream_sys_t ) );
p_sys->i_count = 0;
p_sys->i_count_audio = 0;
p_sys->i_count_video = 0;
p_sys->psz_access = sout_cfg_find_value( p_stream->p_cfg, "access" );
p_sys->psz_access_audio = sout_cfg_find_value( p_stream->p_cfg, "acesss_audio" );
p_sys->psz_access_video = sout_cfg_find_value( p_stream->p_cfg, "access_video" );
p_sys->psz_mux = sout_cfg_find_value( p_stream->p_cfg, "mux" );
p_sys->psz_mux_audio = sout_cfg_find_value( p_stream->p_cfg, "mux_audio" );
p_sys->psz_mux_video = sout_cfg_find_value( p_stream->p_cfg, "mux_video" );
p_sys->psz_url = sout_cfg_find_value( p_stream->p_cfg, "url" );
p_sys->psz_url_audio = sout_cfg_find_value( p_stream->p_cfg, "url_audio" );
p_sys->psz_url_video = sout_cfg_find_value( p_stream->p_cfg, "url_video" );
p_stream->pf_add = Add;
p_stream->pf_del = Del;
p_stream->pf_send = Send;
p_stream->p_sys = p_sys;
return VLC_SUCCESS;
}
/*****************************************************************************
* Close:
*****************************************************************************/
static void Close( vlc_object_t * p_this )
{
sout_stream_t *p_stream = (sout_stream_t*)p_this;
sout_stream_sys_t *p_sys = p_stream->p_sys;
free( p_sys );
}
struct sout_stream_id_t
{
sout_input_t *p_input;
sout_mux_t *p_mux;
};
static char * es_print_url( char *psz_fmt, vlc_fourcc_t i_fourcc, int i_count, char *psz_access, char *psz_mux )
{
char *psz_url, *p;
if( psz_fmt == NULL || !*psz_fmt )
{
psz_fmt = "stream-%n-%c.%m";
}
p = psz_url = malloc( 4096 );
memset( p, 0, 4096 );
for( ;; )
{
if( *psz_fmt == '\0' )
{
*p = '\0';
break;
}
if( *psz_fmt != '%' )
{
*p++ = *psz_fmt++;
}
else
{
if( psz_fmt[1] == 'n' )
{
p += sprintf( p, "%d", i_count );
}
else if( psz_fmt[1] == 'c' )
{
p += sprintf( p, "%4.4s", (char*)&i_fourcc );
}
else if( psz_fmt[1] == 'm' )
{
p += sprintf( p, "%s", psz_mux );
}
else if( psz_fmt[1] == 'a' )
{
p += sprintf( p, "%s", psz_access );
}
else if( psz_fmt[1] != '\0' )
{
p += sprintf( p, "%c%c", psz_fmt[0], psz_fmt[1] );
}
else
{
p += sprintf( p, "%c", psz_fmt[0] );
*p++ = '\0';
break;
}
psz_fmt += 2;
}
}
return( psz_url );
}
static sout_stream_id_t * Add ( sout_stream_t *p_stream, sout_format_t *p_fmt )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
sout_instance_t *p_sout = p_stream->p_sout;
sout_stream_id_t *id;
char *psz_access;
char *psz_mux;
char *psz_url;
sout_access_out_t *p_access;
sout_mux_t *p_mux;
/* *** get access name *** */
if( p_fmt->i_cat == AUDIO_ES && p_sys->psz_access_audio )
{
psz_access = p_sys->psz_access_audio;
}
else if( p_fmt->i_cat == VIDEO_ES && p_sys->psz_access_video )
{
psz_access = p_sys->psz_access_video;
}
else
{
psz_access = p_sys->psz_access;
}
/* *** get mux name *** */
if( p_fmt->i_cat == AUDIO_ES && p_sys->psz_mux_audio )
{
psz_mux = p_sys->psz_mux_audio;
}
else if( p_fmt->i_cat == VIDEO_ES && p_sys->psz_mux_video )
{
psz_mux = p_sys->psz_mux_video;
}
else
{
psz_mux = p_sys->psz_mux;
}
/* *** get url (%d expanded as a codec count, %c expanded as codec fcc ) *** */
if( p_fmt->i_cat == AUDIO_ES && p_sys->psz_url_audio )
{
psz_url = es_print_url( p_sys->psz_url_audio, p_fmt->i_fourcc, p_sys->i_count_audio, psz_access, psz_mux );
}
else if( p_fmt->i_cat == VIDEO_ES && p_sys->psz_url_video )
{
psz_url = es_print_url( p_sys->psz_url_video, p_fmt->i_fourcc, p_sys->i_count_video, psz_access, psz_mux );
}
else
{
int i_count;
if( p_fmt->i_cat == VIDEO_ES )
{
i_count = p_sys->i_count_video;
}
else if( p_fmt->i_cat == AUDIO_ES )
{
i_count = p_sys->i_count_audio;
}
else
{
i_count = p_sys->i_count;
}
psz_url = es_print_url( p_sys->psz_url, p_fmt->i_fourcc, i_count, psz_access, psz_mux );
}
p_sys->i_count++;
if( p_fmt->i_cat == VIDEO_ES )
{
p_sys->i_count_video++;
}
else if( p_fmt->i_cat == AUDIO_ES )
{
p_sys->i_count_audio++;
}
msg_Dbg( p_stream, "creating `%s/%s://%s'",
psz_access, psz_mux, psz_url );
/* *** find and open appropriate access module *** */
p_access = sout_AccessOutNew( p_sout, psz_access, psz_url );
if( p_access == NULL )
{
msg_Err( p_stream, "no suitable sout access module for `%s/%s://%s'",
psz_access, psz_mux, psz_url );
return( NULL );
}
/* *** find and open appropriate mux module *** */
p_mux = sout_MuxNew( p_sout, psz_mux, p_access );
if( p_mux == NULL )
{
msg_Err( p_stream, "no suitable sout mux module for `%s/%s://%s'",
psz_access, psz_mux, psz_url );
sout_AccessOutDelete( p_access );
return( NULL );
}
/* XXX beurk */
p_sout->i_preheader = __MAX( p_sout->i_preheader, p_mux->i_preheader );
id = malloc( sizeof( sout_stream_id_t ) );
id->p_mux = p_mux;
id->p_input = sout_MuxAddStream( p_mux, p_fmt );
if( id->p_input == NULL )
{
free( id );
sout_MuxDelete( p_mux );
sout_AccessOutDelete( p_access );
free( id );
return NULL;
}
return id;
}
static int Del ( sout_stream_t *p_stream, sout_stream_id_t *id )
{
sout_access_out_t *p_access = id->p_mux->p_access;
sout_MuxDeleteStream( id->p_mux, id->p_input );
sout_AccessOutDelete( p_access );
free( id );
return VLC_SUCCESS;
}
static int Send ( sout_stream_t *p_stream, sout_stream_id_t *id, sout_buffer_t *p_buffer )
{
sout_MuxSendBuffer( id->p_mux, id->p_input, p_buffer );
return VLC_SUCCESS;
}
/*****************************************************************************
* standard.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: standard.c,v 1.1 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include <vlc/vlc.h>
#include <vlc/sout.h>
/*****************************************************************************
* Exported prototypes
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static sout_stream_id_t *Add ( sout_stream_t *, sout_format_t * );
static int Del ( sout_stream_t *, sout_stream_id_t * );
static int Send( sout_stream_t *, sout_stream_id_t *, sout_buffer_t* );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("Standard stream") );
set_capability( "sout stream", 50 );
add_shortcut( "standard" );
add_shortcut( "std" );
set_callbacks( Open, Close );
vlc_module_end();
struct sout_stream_sys_t
{
sout_mux_t *p_mux;
};
/*****************************************************************************
* Open:
*****************************************************************************/
static int Open( vlc_object_t *p_this )
{
sout_stream_t *p_stream = (sout_stream_t*)p_this;
sout_instance_t *p_sout = p_stream->p_sout;
sout_stream_sys_t *p_sys;
char *psz_mux = sout_cfg_find_value( p_stream->p_cfg, "mux" );
char *psz_access = sout_cfg_find_value( p_stream->p_cfg, "access" );
char *psz_url = sout_cfg_find_value( p_stream->p_cfg, "url" );
sout_access_out_t *p_access;
sout_mux_t *p_mux;
msg_Dbg( p_this, "creating `%s/%s://%s'",
psz_access, psz_mux, psz_url );
/* *** find and open appropriate access module *** */
p_access = sout_AccessOutNew( p_sout, psz_access, psz_url );
if( p_access == NULL )
{
msg_Err( p_stream, "no suitable sout access module for `%s/%s://%s'",
psz_access, psz_mux, psz_url );
return( VLC_EGENERIC );
}
msg_Dbg( p_stream, "access opened" );
/* *** find and open appropriate mux module *** */
p_mux = sout_MuxNew( p_sout, psz_mux, p_access );
if( p_mux == NULL )
{
msg_Err( p_stream, "no suitable sout mux module for `%s/%s://%s'",
psz_access, psz_mux, psz_url );
sout_AccessOutDelete( p_access );
return( VLC_EGENERIC );
}
msg_Dbg( p_stream, "mux opened" );
/* XXX beurk */
p_sout->i_preheader = __MAX( p_sout->i_preheader, p_mux->i_preheader );
p_sys = malloc( sizeof( sout_stream_sys_t ) );
p_sys->p_mux = p_mux;
p_stream->pf_add = Add;
p_stream->pf_del = Del;
p_stream->pf_send = Send;
p_stream->p_sys = p_sys;
return VLC_SUCCESS;
}
/*****************************************************************************
* Close:
*****************************************************************************/
static void Close( vlc_object_t * p_this )
{
sout_stream_t *p_stream = (sout_stream_t*)p_this;
sout_stream_sys_t *p_sys = p_stream->p_sys;
sout_access_out_t *p_access = p_sys->p_mux->p_access;
sout_MuxDelete( p_sys->p_mux );
sout_AccessOutDelete( p_access );
free( p_sys );
}
struct sout_stream_id_t
{
sout_input_t *p_input;
};
static sout_stream_id_t * Add ( sout_stream_t *p_stream, sout_format_t *p_fmt )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
sout_stream_id_t *id;
id = malloc( sizeof( sout_stream_id_t ) );
if( ( id->p_input = sout_MuxAddStream( p_sys->p_mux, p_fmt ) ) == NULL )
{
free( id );
return NULL;
}
return id;
}
static int Del ( sout_stream_t *p_stream, sout_stream_id_t *id )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
sout_MuxDeleteStream( p_sys->p_mux, id->p_input );
free( id );
return VLC_SUCCESS;
}
static int Send ( sout_stream_t *p_stream, sout_stream_id_t *id, sout_buffer_t *p_buffer )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
sout_MuxSendBuffer( p_sys->p_mux, id->p_input, p_buffer );
return VLC_SUCCESS;
}
This diff is collapsed.
......@@ -2,7 +2,7 @@
* input_dec.c: Functions for the management of decoders
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: input_dec.c,v 1.59 2003/03/04 13:21:19 massiot Exp $
* $Id: input_dec.c,v 1.60 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -58,10 +58,9 @@ decoder_fifo_t * input_RunDecoder( input_thread_t * p_input,
}
p_fifo->p_module = NULL;
/* If we are in sout mode, search first for packetizer module then
* codec to do transcoding */
/* If we are in sout mode, search for packetizer module */
psz_sout = config_GetPsz( p_input, "sout" );
if( psz_sout != NULL && *psz_sout != 0 )
if( !p_es->b_force_decoder && psz_sout != NULL && *psz_sout != 0 )
{
vlc_bool_t b_sout = VLC_TRUE;
......@@ -76,41 +75,9 @@ decoder_fifo_t * input_RunDecoder( input_thread_t * p_input,
if( b_sout )
{
vlc_bool_t b_reencode = VLC_FALSE;
if( p_es->i_cat == AUDIO_ES )
{
char *psz_sout_acodec = config_GetPsz( p_input, "sout-acodec" );
if( psz_sout_acodec != NULL && *psz_sout_acodec != '\0' )
{
msg_Dbg( p_input, "audio reencoding requested -> unsupported" );
b_reencode = VLC_TRUE;
}
}
else if( p_es->i_cat == VIDEO_ES )
{
char *psz_sout_vcodec = config_GetPsz( p_input, "sout-vcodec" );
if( psz_sout_vcodec != NULL && *psz_sout_vcodec != '\0' )
{
msg_Dbg( p_input, "video reencoding requested" );
/* force encoder video output */
config_PutPsz( p_input, "vout", "encoder" );
b_reencode = VLC_TRUE;
}
}
if( !b_reencode )
{
/* we don't want to reencode so search for a packetizer */
p_fifo->p_module =
module_Need( p_fifo, "packetizer", "$packetizer" );
}
else
{
/* get a suitable decoder module to do reencoding*/
p_fifo->p_module = module_Need( p_fifo, "decoder", "$codec" );
}
}
}
else
{
......@@ -118,6 +85,11 @@ decoder_fifo_t * input_RunDecoder( input_thread_t * p_input,
p_fifo->p_module = module_Need( p_fifo, "decoder", "$codec" );
}
if( psz_sout )
{
free( psz_sout );
}
if( p_fifo->p_module == NULL )
{
msg_Err( p_fifo, "no suitable decoder module for fourcc `%4.4s'.\nVLC probably does not support this sound or video format.",
......
......@@ -2,7 +2,7 @@
* input_programs.c: es_descriptor_t, pgrm_descriptor_t management
*****************************************************************************
* Copyright (C) 1999-2002 VideoLAN
* $Id: input_programs.c,v 1.103 2003/03/12 05:26:46 sam Exp $
* $Id: input_programs.c,v 1.104 2003/04/13 20:00:21 fenrir Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -524,6 +524,7 @@ es_descriptor_t * input_AddES( input_thread_t * p_input,
p_es->i_demux_fd = 0;
p_es->c_packets = 0;
p_es->c_invalid_packets = 0;
p_es->b_force_decoder = VLC_FALSE;
if( i_data_len )
{
......
This diff is collapsed.
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