X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fmux%2Favi.c;h=f418914fee3ff7b5734b97f865cfb6e9bc277764;hb=a67afb66baa2aaffeaf71d3b319f44151a5c2516;hp=28a36160d324494a19c6c43472110397c7ec0176;hpb=ad77d955a5dc051976d94d6e08ee0f717ec3a938;p=vlc diff --git a/modules/mux/avi.c b/modules/mux/avi.c index 28a36160d3..f418914fee 100644 --- a/modules/mux/avi.c +++ b/modules/mux/avi.c @@ -1,7 +1,7 @@ /***************************************************************************** * avi.c ***************************************************************************** - * Copyright (C) 2001, 2002 the VideoLAN team + * Copyright (C) 2001-2009 the VideoLAN team * $Id$ * * Authors: Laurent Aimar @@ -75,8 +75,8 @@ typedef struct avi_stream_s float f_fps; int i_bitrate; - BITMAPINFOHEADER *p_bih; - WAVEFORMATEX *p_wf; + VLC_BITMAPINFOHEADER *p_bih; + WAVEFORMATEX *p_wf; } avi_stream_t; @@ -138,7 +138,7 @@ static void SetFCC( uint8_t *p, char *fcc ) static int Open( vlc_object_t *p_this ) { sout_mux_t *p_mux = (sout_mux_t*)p_this; - sout_mux_sys_t *p_sys = p_mux->p_sys; + sout_mux_sys_t *p_sys; msg_Dbg( p_mux, "AVI muxer opened" ); @@ -211,7 +211,7 @@ static void Close( vlc_object_t * p_this ) (uint64_t)p_stream->i_duration; } msg_Info( p_mux, "stream[%d] duration:%"PRId64" totalsize:%"PRId64 - " frames:%d fps:%f kb/s:%d", + " frames:%d fps:%f KiB/s:%d", i_stream, (int64_t)p_stream->i_duration / (int64_t)1000000, p_stream->i_totalsize, @@ -307,9 +307,11 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ) { case VLC_CODEC_A52: p_wf->wFormatTag = WAVE_FORMAT_A52; + p_wf->nBlockAlign= 1; break; case VLC_CODEC_MPGA: p_wf->wFormatTag = WAVE_FORMAT_MPEGLAYER3; + p_wf->nBlockAlign= 1; break; case VLC_CODEC_WMA1: p_wf->wFormatTag = WAVE_FORMAT_WMA1; @@ -328,21 +330,29 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ) p_wf->wFormatTag = WAVE_FORMAT_PCM; p_wf->nBlockAlign= p_wf->nChannels; p_wf->wBitsPerSample = 8; + p_wf->nAvgBytesPerSec = (p_wf->wBitsPerSample/8) * + p_wf->nSamplesPerSec * p_wf->nChannels; break; case VLC_CODEC_S16L: p_wf->wFormatTag = WAVE_FORMAT_PCM; p_wf->nBlockAlign= 2 * p_wf->nChannels; p_wf->wBitsPerSample = 16; + p_wf->nAvgBytesPerSec = (p_wf->wBitsPerSample/8) * + p_wf->nSamplesPerSec * p_wf->nChannels; break; case VLC_CODEC_S24L: p_wf->wFormatTag = WAVE_FORMAT_PCM; p_wf->nBlockAlign= 3 * p_wf->nChannels; p_wf->wBitsPerSample = 24; + p_wf->nAvgBytesPerSec = (p_wf->wBitsPerSample/8) * + p_wf->nSamplesPerSec * p_wf->nChannels; break; case VLC_CODEC_S32L: p_wf->wFormatTag = WAVE_FORMAT_PCM; p_wf->nBlockAlign= 4 * p_wf->nChannels; p_wf->wBitsPerSample = 32; + p_wf->nAvgBytesPerSec = (p_wf->wBitsPerSample/8) * + p_wf->nSamplesPerSec * p_wf->nChannels; break; default: return VLC_EGENERIC; @@ -360,7 +370,7 @@ 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( sizeof( BITMAPINFOHEADER ) + + p_stream->p_bih = malloc( sizeof( VLC_BITMAPINFOHEADER ) + p_input->p_fmt->i_extra ); if( !p_stream->p_bih ) { @@ -368,7 +378,7 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ) return VLC_ENOMEM; } #define p_bih p_stream->p_bih - p_bih->biSize = sizeof( BITMAPINFOHEADER ) + + p_bih->biSize = sizeof( VLC_BITMAPINFOHEADER ) + p_input->p_fmt->i_extra; if( p_input->p_fmt->i_extra > 0 ) { @@ -459,6 +469,24 @@ static int Mux ( sout_mux_t *p_mux ) p_data->i_length = p_next->i_dts - p_data->i_dts; } + + if( p_stream->i_frames == 0 &&p_stream->i_cat == VIDEO_ES ) + { + /* Add header present at the end of BITMAP info header + to first frame in case of XVID */ + if( p_stream->p_bih->biCompression + == VLC_FOURCC( 'X', 'V', 'I', 'D' ) ) + { + int i_header_length = + p_stream->p_bih->biSize - sizeof(VLC_BITMAPINFOHEADER); + p_data = block_Realloc( p_data, + i_header_length, p_data->i_buffer ); + if( !p_data) + return VLC_ENOMEM; + memcpy(p_data->p_buffer,&p_stream->p_bih[1], i_header_length); + } + } + p_stream->i_frames++; if( p_data->i_length < 0 ) { @@ -482,8 +510,8 @@ static int Mux ( sout_mux_t *p_mux ) if( p_sys->idx1.i_entry_count >= p_sys->idx1.i_entry_max ) { p_sys->idx1.i_entry_max += 10000; - p_sys->idx1.entry = realloc( p_sys->idx1.entry, - p_sys->idx1.i_entry_max * sizeof( avi_idx1_entry_t ) ); + p_sys->idx1.entry = xrealloc( p_sys->idx1.entry, + p_sys->idx1.i_entry_max * sizeof( avi_idx1_entry_t ) ); } p_data = block_Realloc( p_data, 8, p_data->i_buffer ); @@ -783,7 +811,7 @@ static int avi_HeaderAdd_strf( buffer_out_t *p_bo, avi_stream_t *p_stream ) bo_AddDWordLE( p_bo, p_stream->p_bih->biClrUsed ); bo_AddDWordLE( p_bo, p_stream->p_bih->biClrImportant ); bo_AddMem( p_bo, - p_stream->p_bih->biSize - sizeof( BITMAPINFOHEADER ), + p_stream->p_bih->biSize - sizeof( VLC_BITMAPINFOHEADER ), (uint8_t*)&p_stream->p_bih[1] ); break; } @@ -806,7 +834,6 @@ static block_t *avi_HeaderCreateRIFF( sout_mux_t *p_mux ) 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; @@ -820,11 +847,16 @@ static block_t *avi_HeaderCreateRIFF( sout_mux_t *p_mux ) bo_AddFCC( &bo, "AVI " ); bo_AddFCC( &bo, "LIST" ); - bo_AddDWordLE( &bo, HDR_SIZE - 8); + /* HDRL List size should exclude following data in HDR buffer + * -12 (RIFF, RIFF size, 'AVI ' tag), + * - 8 (hdr1 LIST tag and its size) + * - 12 (movi LIST tag, size, 'movi' listType ) + */ + bo_AddDWordLE( &bo, HDR_SIZE - 12 - 8 - 12); bo_AddFCC( &bo, "hdrl" ); avi_HeaderAdd_avih( p_mux, &bo ); - for( i_stream = 0,i_maxbytespersec = 0; i_stream < p_sys->i_streams; i_stream++ ) + for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ ) { avi_HeaderAdd_strl( &bo, &p_sys->stream[i_stream] ); } @@ -844,21 +876,20 @@ static block_t *avi_HeaderCreateRIFF( sout_mux_t *p_mux ) static block_t * avi_HeaderCreateidx1( sout_mux_t *p_mux ) { sout_mux_sys_t *p_sys = p_mux->p_sys; - block_t *p_idx1; + block_t *p_idx1; uint32_t i_idx1_size; - unsigned int i; buffer_out_t bo; - i_idx1_size = 16 * p_sys->idx1.i_entry_count; + i_idx1_size = 16 * p_sys->idx1.i_entry_count + 8; - p_idx1 = block_New( p_mux, i_idx1_size + 8 ); - memset( p_idx1->p_buffer, 0, i_idx1_size ); + p_idx1 = block_New( p_mux, i_idx1_size); + 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 ); + bo_AddDWordLE( &bo, i_idx1_size - 8); - for( i = 0; i < p_sys->idx1.i_entry_count; i++ ) + for( unsigned i = 0; i < p_sys->idx1.i_entry_count; i++ ) { bo_AddFCC( &bo, p_sys->idx1.entry[i].fcc ); bo_AddDWordLE( &bo, p_sys->idx1.entry[i].i_flags );