X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fmux%2Favi.c;h=0d2c4b6f4b3fbe80ad78780f55ac0f4aa5c12746;hb=1ce4f166a9653d8ee369862ee3111cce91af815d;hp=bb60e2238e86ea8f34bce0963c2328522cb67225;hpb=453d866aa156b7faf0d87f8ffbf31f5f77748872;p=vlc diff --git a/modules/mux/avi.c b/modules/mux/avi.c index bb60e2238e..0d2c4b6f4b 100644 --- a/modules/mux/avi.c +++ b/modules/mux/avi.c @@ -1,8 +1,8 @@ /***************************************************************************** * avi.c ***************************************************************************** - * Copyright (C) 2001, 2002 VideoLAN - * $Id: avi.c,v 1.7 2003/02/24 12:34:29 fenrir Exp $ + * Copyright (C) 2001-2009 the VideoLAN team + * $Id$ * * Authors: Laurent Aimar * @@ -18,7 +18,7 @@ * * 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. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** @@ -26,81 +26,40 @@ *****************************************************************************/ /* TODO: add OpenDML write support */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef HAVE_UNISTD_H -# include -#elif defined( _MSC_VER ) && defined( _WIN32 ) && !defined( UNDER_CE ) -# include -#endif - -#include "codecs.h" - -#define AVIF_HASINDEX 0x00000010 // Index at end of file? -#define AVIF_MUSTUSEINDEX 0x00000020 -#define AVIF_ISINTERLEAVED 0x00000100 -#define AVIF_TRUSTCKTYPE 0x00000800 // Use CKType to find key frames? -#define AVIF_WASCAPTUREFILE 0x00010000 -#define AVIF_COPYRIGHTED 0x00020000 +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif -/* Flags for index */ -#define AVIIF_LIST 0x00000001L /* chunk is a 'LIST' */ -#define AVIIF_KEYFRAME 0x00000010L /* this frame is a key frame.*/ -#define AVIIF_NOTIME 0x00000100L /* this frame doesn't take any time */ -#define AVIIF_COMPUSE 0x0FFF0000L /* these bits are for compressor use */ +#include +#include +#include +#include +#include /***************************************************************************** - * Exported prototypes + * Module descriptor *****************************************************************************/ -static int Open ( vlc_object_t * ); -static void Close ( vlc_object_t * ); - -static int Capability( int , void *, void * ); -static int AddStream( sout_instance_t *, sout_input_t * ); -static int DelStream( sout_instance_t *, sout_input_t * ); -static int Mux ( sout_instance_t * ); - -static sout_buffer_t *avi_HeaderCreateRIFF( sout_instance_t *p_sout ); -static sout_buffer_t *avi_HeaderCreateidx1( sout_instance_t *p_sout ); +static int Open ( vlc_object_t * ); +static void Close ( vlc_object_t * ); -static void SetFCC( uint8_t *p, char *fcc ) -{ - p[0] = fcc[0]; - p[1] = fcc[1]; - p[2] = fcc[2]; - p[3] = fcc[3]; -} +vlc_module_begin () + set_description( N_("AVI muxer") ) + set_category( CAT_SOUT ) + set_subcategory( SUBCAT_SOUT_MUX ) + set_capability( "sout mux", 5 ) + add_shortcut( "avi" ) + set_callbacks( Open, Close ) +vlc_module_end () -static void SetDWLE( uint8_t *p, uint32_t i_dw ) -{ - p[3] = ( i_dw >> 24 )&0xff; - p[2] = ( i_dw >> 16 )&0xff; - p[1] = ( i_dw >> 8 )&0xff; - p[0] = ( i_dw )&0xff; -} /***************************************************************************** - * Module descriptor + * Local prototypes *****************************************************************************/ -vlc_module_begin(); - set_description( _("Avi muxer") ); - set_capability( "sout mux", 5 ); - add_shortcut( "avi" ); - set_callbacks( Open, Close ); -vlc_module_end(); - -// FIXME FIXME -#define HDR_SIZE 10240 +static int Control( sout_mux_t *, int, va_list ); +static int AddStream( sout_mux_t *, sout_input_t * ); +static int DelStream( sout_mux_t *, sout_input_t * ); +static int Mux ( sout_mux_t * ); typedef struct avi_stream_s { @@ -108,7 +67,7 @@ typedef struct avi_stream_s char fcc[4]; - mtime_t i_duration; // in µs + mtime_t i_duration; // in µs int i_frames; // total frame count int64_t i_totalsize; // total stream size @@ -138,8 +97,10 @@ typedef struct avi_idx1_s avi_idx1_entry_t *entry; } avi_idx1_t; -typedef struct sout_mux_s +struct sout_mux_sys_t { + bool b_write_header; + int i_streams; int i_stream_video; @@ -149,39 +110,62 @@ typedef struct sout_mux_s avi_idx1_t idx1; off_t i_idx1_size; -} sout_mux_t; +}; + +// FIXME FIXME +#define HDR_SIZE 10240 + +/* Flags in avih */ +#define AVIF_HASINDEX 0x00000010 // Index at end of file? +#define AVIF_ISINTERLEAVED 0x00000100 +#define AVIF_TRUSTCKTYPE 0x00000800 // Use CKType to find key frames? + +/* Flags for index */ +#define AVIIF_KEYFRAME 0x00000010L /* this frame is a key frame.*/ + + +static block_t *avi_HeaderCreateRIFF( sout_mux_t * ); +static block_t *avi_HeaderCreateidx1( sout_mux_t * ); + +static void SetFCC( uint8_t *p, char *fcc ) +{ + memcpy( p, fcc, 4 ); +} /***************************************************************************** * Open: *****************************************************************************/ static int Open( vlc_object_t *p_this ) { - sout_instance_t *p_sout = (sout_instance_t*)p_this; - sout_mux_t *p_mux; - sout_buffer_t *p_hdr; - - p_mux = malloc( sizeof( sout_mux_t ) ); - p_mux->i_streams = 0; - p_mux->i_stream_video = -1; - p_mux->i_movi_size = 0; - - p_mux->idx1.i_entry_count = 0; - p_mux->idx1.i_entry_max = 10000; - p_mux->idx1.entry = calloc( p_mux->idx1.i_entry_max, sizeof( avi_idx1_entry_t ) ); - - msg_Info( p_sout, "Open" ); - - p_sout->pf_mux_capacity = Capability; - p_sout->pf_mux_addstream = AddStream; - p_sout->pf_mux_delstream = DelStream; - p_sout->pf_mux = Mux; - p_sout->p_mux_data = (void*)p_mux; - p_sout->i_mux_preheader = 8; // (fourcc,length) header - - /* room to add header at the end */ - p_hdr = sout_BufferNew( p_sout, HDR_SIZE ); - memset( p_hdr->p_buffer, 0, HDR_SIZE ); - sout_AccessOutWrite( p_sout->p_access, p_hdr ); + sout_mux_t *p_mux = (sout_mux_t*)p_this; + sout_mux_sys_t *p_sys; + + msg_Dbg( p_mux, "AVI muxer opened" ); + + p_sys = malloc( sizeof( sout_mux_sys_t ) ); + if( !p_sys ) + return VLC_ENOMEM; + p_sys->i_streams = 0; + p_sys->i_stream_video = -1; + p_sys->i_movi_size = 0; + + p_sys->idx1.i_entry_count = 0; + p_sys->idx1.i_entry_max = 10000; + p_sys->idx1.entry = calloc( p_sys->idx1.i_entry_max, + sizeof( avi_idx1_entry_t ) ); + if( !p_sys->idx1.entry ) + { + free( p_sys ); + return VLC_ENOMEM; + } + p_sys->b_write_header = true; + + + p_mux->pf_control = Control; + p_mux->pf_addstream = AddStream; + p_mux->pf_delstream = DelStream; + p_mux->pf_mux = Mux; + p_mux->p_sys = p_sys; return VLC_SUCCESS; } @@ -189,27 +173,27 @@ static int Open( vlc_object_t *p_this ) /***************************************************************************** * Close: *****************************************************************************/ - static void Close( vlc_object_t * p_this ) { - sout_instance_t *p_sout = (sout_instance_t*)p_this; - sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data; - sout_buffer_t *p_hdr, *p_idx1; + sout_mux_t *p_mux = (sout_mux_t*)p_this; + sout_mux_sys_t *p_sys = p_mux->p_sys; + + block_t *p_hdr, *p_idx1; int i_stream; - msg_Info( p_sout, "Close" ); + msg_Dbg( p_mux, "AVI muxer closed" ); /* first create idx1 chunk (write at the end of the stream */ - p_idx1 = avi_HeaderCreateidx1( p_sout ); - p_mux->i_idx1_size = p_idx1->i_size; - sout_AccessOutWrite( p_sout->p_access, p_idx1 ); + p_idx1 = avi_HeaderCreateidx1( p_mux ); + p_sys->i_idx1_size = p_idx1->i_buffer; + sout_AccessOutWrite( p_mux->p_access, p_idx1 ); /* calculate some value for headers creations */ - for( i_stream = 0; i_stream < p_mux->i_streams; i_stream++ ) + for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ ) { avi_stream_t *p_stream; - p_stream = &p_mux->stream[i_stream]; + p_stream = &p_sys->stream[i_stream]; p_stream->f_fps = 25; if( p_stream->i_duration > 0 ) @@ -226,185 +210,297 @@ static void Close( vlc_object_t * p_this ) (uint64_t)p_stream->i_totalsize / (uint64_t)p_stream->i_duration; } - msg_Err( p_sout,"stream[%d] duration:%lld totalsize:%lld frames:%d fps:%f kb/s:%d", - i_stream, - p_stream->i_duration/1000000, p_stream->i_totalsize, - p_stream->i_frames, - p_stream->f_fps, p_stream->i_bitrate/1024 ); + msg_Info( p_mux, "stream[%d] duration:%"PRId64" totalsize:%"PRId64 + " frames:%d fps:%f KiB/s:%d", + i_stream, + (int64_t)p_stream->i_duration / (int64_t)1000000, + p_stream->i_totalsize, + p_stream->i_frames, + p_stream->f_fps, p_stream->i_bitrate/1024 ); } - p_hdr = avi_HeaderCreateRIFF( p_sout ); - sout_AccessOutSeek( p_sout->p_access, 0 ); - sout_AccessOutWrite( p_sout->p_access, p_hdr ); + p_hdr = avi_HeaderCreateRIFF( p_mux ); + sout_AccessOutSeek( p_mux->p_access, 0 ); + sout_AccessOutWrite( p_mux->p_access, p_hdr ); } -static int Capability( int i_query, void *p_args, void *p_answer ) +static int Control( sout_mux_t *p_mux, int i_query, va_list args ) { + VLC_UNUSED(p_mux); + bool *pb_bool; + char **ppsz; + switch( i_query ) { - case SOUT_MUX_CAP_GET_ADD_STREAM_ANY_TIME: - *(vlc_bool_t*)p_answer = VLC_TRUE; - return( SOUT_MUX_CAP_ERR_OK ); + case MUX_CAN_ADD_STREAM_WHILE_MUXING: + pb_bool = (bool*)va_arg( args, bool * ); + *pb_bool = false; + return VLC_SUCCESS; + + case MUX_GET_ADD_STREAM_WAIT: + pb_bool = (bool*)va_arg( args, bool * ); + *pb_bool = true; + return VLC_SUCCESS; + + case MUX_GET_MIME: + ppsz = (char**)va_arg( args, char ** ); + *ppsz = strdup( "video/avi" ); + return VLC_SUCCESS; + default: - return( SOUT_MUX_CAP_ERR_UNIMPLEMENTED ); + return VLC_EGENERIC; } } -static int AddStream( sout_instance_t *p_sout, sout_input_t *p_input ) +static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ) { - sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data; - avi_stream_t *p_stream; + sout_mux_sys_t *p_sys = p_mux->p_sys; + avi_stream_t *p_stream; - if( p_mux->i_streams >= 100 ) - { - msg_Err( p_sout, "too many streams" ); - return( -1 ); - } - if( p_input->input_format.p_format == NULL ) + if( p_sys->i_streams >= 100 ) { - msg_Err( p_sout, "stream descriptor missing" ); - return( -1 ); + msg_Err( p_mux, "too many streams" ); + return VLC_EGENERIC; } - msg_Dbg( p_sout, "adding input" ); - p_input->p_mux_data = malloc( sizeof( int ) ); + msg_Dbg( p_mux, "adding input" ); + p_input->p_sys = malloc( sizeof( int ) ); + if( !p_input->p_sys ) + return VLC_ENOMEM; - *((int*)p_input->p_mux_data) = p_mux->i_streams; - p_stream = &p_mux->stream[p_mux->i_streams]; + *((int*)p_input->p_sys) = p_sys->i_streams; + p_stream = &p_sys->stream[p_sys->i_streams]; - switch( p_input->input_format.i_cat ) + switch( p_input->p_fmt->i_cat ) { case AUDIO_ES: + 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; + p_stream->fcc[2] = 'w'; + p_stream->fcc[3] = 'b'; + + p_stream->p_bih = NULL; + + p_stream->p_wf = malloc( sizeof( WAVEFORMATEX ) + + p_input->p_fmt->i_extra ); + if( !p_stream->p_wf ) + { + free( p_input->p_sys ); + return VLC_ENOMEM; + } +#define p_wf p_stream->p_wf + p_wf->cbSize = p_input->p_fmt->i_extra; + if( p_wf->cbSize > 0 ) + { + memcpy( &p_wf[1], + p_input->p_fmt->p_extra, + p_input->p_fmt->i_extra ); + } + p_wf->nChannels = p_input->p_fmt->audio.i_channels; + p_wf->nSamplesPerSec = p_input->p_fmt->audio.i_rate; + p_wf->nBlockAlign = p_input->p_fmt->audio.i_blockalign; + p_wf->nAvgBytesPerSec= p_input->p_fmt->i_bitrate / 8; + p_wf->wBitsPerSample = 0; + + switch( p_input->p_fmt->i_codec ) { - WAVEFORMATEX *p_wf = - (WAVEFORMATEX*)p_input->input_format.p_format; - - p_stream->i_cat = AUDIO_ES; - p_stream->fcc[0] = '0' + p_mux->i_streams / 10; - p_stream->fcc[1] = '0' + p_mux->i_streams % 10; - p_stream->fcc[2] = 'w'; - 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); + case VLC_CODEC_A52: + p_wf->wFormatTag = WAVE_FORMAT_A52; + break; + case VLC_CODEC_MPGA: + p_wf->wFormatTag = WAVE_FORMAT_MPEGLAYER3; + break; + case VLC_CODEC_WMA1: + p_wf->wFormatTag = WAVE_FORMAT_WMA1; + break; + case VLC_CODEC_WMA2: + p_wf->wFormatTag = WAVE_FORMAT_WMA2; + break; + case VLC_CODEC_WMAP: + p_wf->wFormatTag = WAVE_FORMAT_WMAP; + break; + case VLC_CODEC_WMAL: + p_wf->wFormatTag = WAVE_FORMAT_WMAL; + break; + /* raw codec */ + case VLC_CODEC_U8: + p_wf->wFormatTag = WAVE_FORMAT_PCM; + p_wf->nBlockAlign= p_wf->nChannels; + p_wf->wBitsPerSample = 8; + break; + case VLC_CODEC_S16L: + p_wf->wFormatTag = WAVE_FORMAT_PCM; + p_wf->nBlockAlign= 2 * p_wf->nChannels; + p_wf->wBitsPerSample = 16; + break; + case VLC_CODEC_S24L: + p_wf->wFormatTag = WAVE_FORMAT_PCM; + p_wf->nBlockAlign= 3 * p_wf->nChannels; + p_wf->wBitsPerSample = 24; + break; + case VLC_CODEC_S32L: + p_wf->wFormatTag = WAVE_FORMAT_PCM; + p_wf->nBlockAlign= 4 * p_wf->nChannels; + p_wf->wBitsPerSample = 32; + break; + default: + return VLC_EGENERIC; } +#undef p_wf break; case VIDEO_ES: + 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; + p_stream->fcc[2] = 'd'; + p_stream->fcc[3] = 'c'; + if( p_sys->i_stream_video < 0 ) { - BITMAPINFOHEADER *p_bih = - (BITMAPINFOHEADER*)p_input->input_format.p_format;; - - p_stream->i_cat = VIDEO_ES; - p_stream->fcc[0] = '0' + p_mux->i_streams / 10; - p_stream->fcc[1] = '0' + p_mux->i_streams % 10; - p_stream->fcc[2] = 'd'; - p_stream->fcc[3] = 'c'; - if( p_mux->i_stream_video < 0 ) - { - p_mux->i_stream_video = p_mux->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_sys->i_stream_video = p_sys->i_streams; } + p_stream->p_wf = NULL; + p_stream->p_bih = malloc( sizeof( BITMAPINFOHEADER ) + + p_input->p_fmt->i_extra ); + if( !p_stream->p_bih ) + { + free( p_input->p_sys ); + return VLC_ENOMEM; + } +#define p_bih p_stream->p_bih + p_bih->biSize = sizeof( BITMAPINFOHEADER ) + + p_input->p_fmt->i_extra; + if( p_input->p_fmt->i_extra > 0 ) + { + memcpy( &p_bih[1], + p_input->p_fmt->p_extra, + p_input->p_fmt->i_extra ); + } + p_bih->biWidth = p_input->p_fmt->video.i_width; + p_bih->biHeight= p_input->p_fmt->video.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_codec ) + { + case VLC_CODEC_MP4V: + p_bih->biCompression = VLC_FOURCC( 'X', 'V', 'I', 'D' ); + break; + default: + p_bih->biCompression = p_input->p_fmt->i_original_fourcc ?: p_input->p_fmt->i_codec; + break; + } +#undef p_bih break; default: - return( -1 ); + return( VLC_EGENERIC ); } p_stream->i_totalsize = 0; - p_stream->i_frames = 0; + p_stream->i_frames = 0; p_stream->i_duration = 0; - p_mux->i_streams++; - return( 0 ); + /* fixed later */ + p_stream->f_fps = 25; + p_stream->i_bitrate = 128 * 1024; + + p_sys->i_streams++; + return( VLC_SUCCESS ); } -static int DelStream( sout_instance_t *p_sout, sout_input_t *p_input ) +static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input ) { -// 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; - - return( 0 ); + free( p_input->p_sys ); + return 0; } -static int Mux ( sout_instance_t *p_sout ) +static int Mux ( sout_mux_t *p_mux ) { - sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data; - avi_stream_t *p_stream; - int i_stream; - int i; + sout_mux_sys_t *p_sys = p_mux->p_sys; + avi_stream_t *p_stream; + int i_stream, i; - for( i = 0; i < p_sout->i_nb_inputs; i++ ) + if( p_sys->b_write_header ) + { + block_t *p_hdr; + + msg_Dbg( p_mux, "writing header" ); + + p_hdr = avi_HeaderCreateRIFF( p_mux ); + sout_AccessOutWrite( p_mux->p_access, p_hdr ); + + p_sys->b_write_header = false; + } + + for( i = 0; i < p_mux->i_nb_inputs; i++ ) { int i_count; - sout_fifo_t *p_fifo; + block_fifo_t *p_fifo; - i_stream = *((int*)p_sout->pp_inputs[i]->p_mux_data ); - p_stream = &p_mux->stream[i_stream]; + i_stream = *((int*)p_mux->pp_inputs[i]->p_sys ); + p_stream = &p_sys->stream[i_stream]; - p_fifo = p_sout->pp_inputs[i]->p_fifo; - i_count = p_fifo->i_depth; - while( i_count > 0 ) + p_fifo = p_mux->pp_inputs[i]->p_fifo; + i_count = block_FifoCount( p_fifo ); + while( i_count > 1 ) { avi_idx1_entry_t *p_idx; - sout_buffer_t *p_data; + block_t *p_data; - p_data = sout_FifoGet( p_fifo ); + p_data = block_FifoGet( p_fifo ); + if( block_FifoCount( p_fifo ) > 0 ) + { + block_t *p_next = block_FifoShow( p_fifo ); + p_data->i_length = p_next->i_dts - p_data->i_dts; + } p_stream->i_frames++; + if( p_data->i_length < 0 ) + { + msg_Warn( p_mux, "argg length < 0 l" ); + block_Release( p_data ); + i_count--; + continue; + } p_stream->i_duration += p_data->i_length; - p_stream->i_totalsize += p_data->i_size; + p_stream->i_totalsize += p_data->i_buffer; /* add idx1 entry for this frame */ - p_idx = &p_mux->idx1.entry[p_mux->idx1.i_entry_count]; + p_idx = &p_sys->idx1.entry[p_sys->idx1.i_entry_count]; memcpy( p_idx->fcc, p_stream->fcc, 4 ); - p_idx->i_flags = AVIIF_KEYFRAME; - p_idx->i_pos = p_mux->i_movi_size + 4; - p_idx->i_length= p_data->i_size; - p_mux->idx1.i_entry_count++; - if( p_mux->idx1.i_entry_count >= p_mux->idx1.i_entry_max ) + p_idx->i_flags = 0; + if( ( p_data->i_flags & BLOCK_FLAG_TYPE_MASK ) == 0 || ( p_data->i_flags & BLOCK_FLAG_TYPE_I ) ) + p_idx->i_flags = AVIIF_KEYFRAME; + p_idx->i_pos = p_sys->i_movi_size + 4; + p_idx->i_length= p_data->i_buffer; + p_sys->idx1.i_entry_count++; + if( p_sys->idx1.i_entry_count >= p_sys->idx1.i_entry_max ) { - p_mux->idx1.i_entry_max += 10000; - p_mux->idx1.entry = realloc( p_mux->idx1.entry, - p_mux->idx1.i_entry_max * sizeof( avi_idx1_entry_t ) ); + p_sys->idx1.i_entry_max += 10000; + p_sys->idx1.entry = xrealloc( p_sys->idx1.entry, + p_sys->idx1.i_entry_max * sizeof( avi_idx1_entry_t ) ); } - - if( sout_BufferReallocFromPreHeader( p_sout, p_data, 8 ) ) - { - /* there isn't enough data in preheader */ - sout_buffer_t *p_hdr; - - p_hdr = sout_BufferNew( p_sout, 8 ); - SetFCC( p_hdr->p_buffer, p_stream->fcc ); - SetDWLE( p_hdr->p_buffer + 4, p_data->i_size ); - - sout_AccessOutWrite( p_sout->p_access, p_hdr ); - p_mux->i_movi_size += p_hdr->i_size; - - } - else + p_data = block_Realloc( p_data, 8, p_data->i_buffer ); + if( p_data ) { SetFCC( p_data->p_buffer, p_stream->fcc ); - SetDWLE( p_data->p_buffer + 4, p_data->i_size - 8 ); - } + SetDWLE( p_data->p_buffer + 4, p_data->i_buffer - 8 ); - if( p_data->i_size & 0x01 ) - { - sout_BufferRealloc( p_sout, p_data, p_data->i_size + 1 ); - p_data->i_size += 1; - } + if( p_data->i_buffer & 0x01 ) + { + p_data = block_Realloc( p_data, 0, p_data->i_buffer + 1 ); + p_data->p_buffer[ p_data->i_buffer - 1 ] = '\0'; + } - sout_AccessOutWrite( p_sout->p_access, p_data ); - p_mux->i_movi_size += p_data->i_size; + p_sys->i_movi_size += p_data->i_buffer; + sout_AccessOutWrite( p_mux->p_access, p_data ); + } i_count--; } @@ -473,7 +569,7 @@ static void bo_AddLWordBE( buffer_out_t *p_bo, uint64_t i ) } #endif -static void bo_AddFCC( buffer_out_t *p_bo, char *fcc ) +static void bo_AddFCC( buffer_out_t *p_bo, const char *fcc ) { bo_AddByte( p_bo, fcc[0] ); bo_AddByte( p_bo, fcc[1] ); @@ -513,23 +609,23 @@ 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 ); \ return( i_err ); -static int avi_HeaderAdd_avih( sout_instance_t *p_sout, +static int avi_HeaderAdd_avih( sout_mux_t *p_mux, buffer_out_t *p_bo ) { - sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data; - avi_stream_t *p_video = NULL; + sout_mux_sys_t *p_sys = p_mux->p_sys; + avi_stream_t *p_video = NULL; int i_stream; uint32_t i_microsecperframe; int i_maxbytespersec; int i_totalframes; AVI_BOX_ENTER( "avih" ); - if( p_mux->i_stream_video >= 0 ) + if( p_sys->i_stream_video >= 0 ) { - p_video = &p_mux->stream[p_mux->i_stream_video]; + p_video = &p_sys->stream[p_sys->i_stream_video]; if( p_video->i_frames <= 0 ) { - p_video = NULL; + // p_video = NULL; } } @@ -537,23 +633,23 @@ static int avi_HeaderAdd_avih( sout_instance_t *p_sout, { i_microsecperframe = (uint32_t)( (float)1000000 / - (float)p_mux->stream[p_mux->i_stream_video].f_fps ); - i_totalframes = p_mux->stream[p_mux->i_stream_video].i_frames; + (float)p_sys->stream[p_sys->i_stream_video].f_fps ); + i_totalframes = p_sys->stream[p_sys->i_stream_video].i_frames; } else { - msg_Warn( p_sout, "avi file without audio video track isn't a good idea..." ); + msg_Warn( p_mux, "avi file without video track isn't a good idea..." ); i_microsecperframe = 0; i_totalframes = 0; } - for( i_stream = 0,i_maxbytespersec = 0; i_stream < p_mux->i_streams; i_stream++ ) + for( i_stream = 0,i_maxbytespersec = 0; i_stream < p_sys->i_streams; i_stream++ ) { - if( p_mux->stream[p_mux->i_stream_video].i_duration > 0 ) + if( p_sys->stream[i_stream].i_duration > 0 ) { i_maxbytespersec += - p_mux->stream[p_mux->i_stream_video].i_totalsize / - p_mux->stream[p_mux->i_stream_video].i_duration; + p_sys->stream[i_stream].i_totalsize / + p_sys->stream[i_stream].i_duration; } } @@ -565,7 +661,7 @@ static int avi_HeaderAdd_avih( sout_instance_t *p_sout, AVIF_ISINTERLEAVED ); /* flags */ bo_AddDWordLE( p_bo, i_totalframes ); bo_AddDWordLE( p_bo, 0 ); /* initial frame */ - bo_AddDWordLE( p_bo, p_mux->i_streams ); /* streams count */ + bo_AddDWordLE( p_bo, p_sys->i_streams ); /* streams count */ bo_AddDWordLE( p_bo, 1024 * 1024 ); /* suggested buffer size */ if( p_video ) { @@ -584,11 +680,8 @@ static int avi_HeaderAdd_avih( sout_instance_t *p_sout, AVI_BOX_EXIT( 0 ); } -static int avi_HeaderAdd_strh( sout_instance_t *p_sout, - buffer_out_t *p_bo, - avi_stream_t *p_stream ) +static int avi_HeaderAdd_strh( buffer_out_t *p_bo, avi_stream_t *p_stream ) { -// sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data; AVI_BOX_ENTER( "strh" ); switch( p_stream->i_cat ) @@ -622,7 +715,7 @@ static int avi_HeaderAdd_strh( sout_instance_t *p_sout, 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 { @@ -654,11 +747,8 @@ static int avi_HeaderAdd_strh( sout_instance_t *p_sout, AVI_BOX_EXIT( 0 ); } -static int avi_HeaderAdd_strf( sout_instance_t *p_sout, - buffer_out_t *p_bo, - avi_stream_t *p_stream ) +static int avi_HeaderAdd_strf( buffer_out_t *p_bo, avi_stream_t *p_stream ) { -// sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data; AVI_BOX_ENTER( "strf" ); switch( p_stream->i_cat ) @@ -701,45 +791,41 @@ static int avi_HeaderAdd_strf( sout_instance_t *p_sout, AVI_BOX_EXIT( 0 ); } -static int avi_HeaderAdd_strl( sout_instance_t *p_sout, - buffer_out_t *p_bo, - avi_stream_t *p_stream ) +static int avi_HeaderAdd_strl( buffer_out_t *p_bo, avi_stream_t *p_stream ) { -// sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data; AVI_BOX_ENTER_LIST( "strl" ); - avi_HeaderAdd_strh( p_sout, p_bo, p_stream ); - avi_HeaderAdd_strf( p_sout, p_bo, p_stream ); + avi_HeaderAdd_strh( p_bo, p_stream ); + avi_HeaderAdd_strf( p_bo, p_stream ); AVI_BOX_EXIT( 0 ); } -static sout_buffer_t *avi_HeaderCreateRIFF( sout_instance_t *p_sout ) +static block_t *avi_HeaderCreateRIFF( sout_mux_t *p_mux ) { - sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data; - sout_buffer_t *p_hdr; + sout_mux_sys_t *p_sys = p_mux->p_sys; + block_t *p_hdr; int i_stream; - int i_maxbytespersec; int i_junk; buffer_out_t bo; - p_hdr = sout_BufferNew( p_sout, HDR_SIZE ); + p_hdr = block_New( p_mux, HDR_SIZE ); memset( p_hdr->p_buffer, 0, HDR_SIZE ); bo_Init( &bo, HDR_SIZE, p_hdr->p_buffer ); bo_AddFCC( &bo, "RIFF" ); - bo_AddDWordLE( &bo, p_mux->i_movi_size + HDR_SIZE - 8 + p_mux->i_idx1_size ); + bo_AddDWordLE( &bo, p_sys->i_movi_size + HDR_SIZE - 8 + p_sys->i_idx1_size ); bo_AddFCC( &bo, "AVI " ); bo_AddFCC( &bo, "LIST" ); bo_AddDWordLE( &bo, HDR_SIZE - 8); bo_AddFCC( &bo, "hdrl" ); - avi_HeaderAdd_avih( p_sout, &bo ); - for( i_stream = 0,i_maxbytespersec = 0; i_stream < p_mux->i_streams; i_stream++ ) + avi_HeaderAdd_avih( p_mux, &bo ); + for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ ) { - avi_HeaderAdd_strl( p_sout, &bo, &p_mux->stream[i_stream] ); + avi_HeaderAdd_strl( &bo, &p_sys->stream[i_stream] ); } i_junk = HDR_SIZE - bo.i_buffer - 8 - 12; @@ -748,38 +834,37 @@ static sout_buffer_t *avi_HeaderCreateRIFF( sout_instance_t *p_sout ) bo.i_buffer += i_junk; bo_AddFCC( &bo, "LIST" ); - bo_AddDWordLE( &bo, p_mux->i_movi_size + 4 ); + bo_AddDWordLE( &bo, p_sys->i_movi_size + 4 ); bo_AddFCC( &bo, "movi" ); return( p_hdr ); } -static sout_buffer_t * avi_HeaderCreateidx1( sout_instance_t *p_sout ) +static block_t * avi_HeaderCreateidx1( sout_mux_t *p_mux ) { - sout_mux_t *p_mux = (sout_mux_t*)p_sout->p_mux_data; - sout_buffer_t *p_idx1; + sout_mux_sys_t *p_sys = p_mux->p_sys; + block_t *p_idx1; uint32_t i_idx1_size; unsigned int i; buffer_out_t bo; - i_idx1_size = 16 * p_mux->idx1.i_entry_count; + i_idx1_size = 16 * p_sys->idx1.i_entry_count; - p_idx1 = sout_BufferNew( p_sout, i_idx1_size + 8 ); + p_idx1 = block_New( p_mux, i_idx1_size + 8 ); memset( p_idx1->p_buffer, 0, i_idx1_size ); bo_Init( &bo, i_idx1_size, p_idx1->p_buffer ); bo_AddFCC( &bo, "idx1" ); bo_AddDWordLE( &bo, i_idx1_size ); - for( i = 0; i < p_mux->idx1.i_entry_count; i++ ) + for( i = 0; i < p_sys->idx1.i_entry_count; i++ ) { - bo_AddFCC( &bo, p_mux->idx1.entry[i].fcc ); - bo_AddDWordLE( &bo, p_mux->idx1.entry[i].i_flags ); - bo_AddDWordLE( &bo, p_mux->idx1.entry[i].i_pos ); - bo_AddDWordLE( &bo, p_mux->idx1.entry[i].i_length ); + bo_AddFCC( &bo, p_sys->idx1.entry[i].fcc ); + bo_AddDWordLE( &bo, p_sys->idx1.entry[i].i_flags ); + bo_AddDWordLE( &bo, p_sys->idx1.entry[i].i_pos ); + bo_AddDWordLE( &bo, p_sys->idx1.entry[i].i_length ); } return( p_idx1 ); } -