/*****************************************************************************
* avi.c
*****************************************************************************
- * Copyright (C) 2001, 2002 the VideoLAN team
+ * Copyright (C) 2001-2009 the VideoLAN team
* $Id$
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
float f_fps;
int i_bitrate;
- BITMAPINFOHEADER *p_bih;
- WAVEFORMATEX *p_wf;
+ VLC_BITMAPINFOHEADER *p_bih;
+ WAVEFORMATEX *p_wf;
} avi_stream_t;
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" );
(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,
{
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;
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;
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 )
{
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 )
{
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 )
{
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 );
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;
}
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;
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] );
}
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 );