[vlc-commits] Fixed bugs in AVI mux module
Ashok Bhat
git at videolan.org
Sun Jun 12 16:07:17 CEST 2011
vlc | branch: master | Ashok Bhat <ashok.bhat at gmail.com> | Thu Jun 9 19:25:05 2011 +0530| [1e6d1f3cb3d0ee4b36a939b17eb3a1de2131d34d] | committer: Jean-Baptiste Kempf
Fixed bugs in AVI mux module
Closes #21 (partly, at least), #4288 and #4304
Description
===================
Fixed bugs in AVI mux to support creation of AVI files with following popular video/audio combinations
(a) MPEG4 video (aka XVID) with MP3/AC3/PCM Audio
(b) MJPEG video with PCM audio.
AVI as such is not used for storing other formats like H.264, AAC etc
Bug fix details
===================
(a) 'hdrl' list size was wrong. It incorrectly included some parts of MOVI list, size taken by hdrl LIST tag and its size and Size of 'RIFF', File size and 'AVI ' type.
(b) Block Align was set to 0 in case of MP3/AC3. It has to be non-zero. It has to been set to 1.
(c) XVID video decoders expect header to present as part of first frame. Added code to append header present at end of BITMAPINFOHEADER to beginning of the first video frame in case of XVID video.
(d) nAvgBytesPerSec of Waveformatex was not properly being set in case of PCM audio.
(e) Last index entry value was set to garbage due to incorrect index size calculation.
Test PC configuration
===================
Tested with Windows Media Player 11 installed on Windows XP Service pack 3 machine with following directshow filters installed
(a) XVID MPEG4 video decoder filter for MPEG4 video decoding
(b) LAME MP3 codec for MP3 audio decoding
Combinations tested
====================
(a) MPEG4/MP3 transcode
vlc -I dummy "Mr_MrsSmith-h264_aac.mp4" :sout="#transcode{vcodec=mp4v,vb=1024,fps=25,acodec=mpga,ab=128}:standard{mux=avi,access=file,dst=out.avi}" vlc://quit
(b) MPEG4/AC3 transcode
vlc -I dummy "Mr_MrsSmith-h264_aac.mp4" :sout="#transcode{vcodec=mp4v,vb=1024,fps=25,acodec=a52, ab=128}:standard{mux=avi,access=file,dst=out.avi}" vlc://quit
(c) MPEG4/PCM(16bit) transcode
vlc -I dummy "Mr_MrsSmith-h264_aac.mp4" :sout="#transcode{vcodec=mp4v,vb=1024,fps=25,acodec=s16l}:standard{mux=avi,access=file,dst=out.avi}" vlc://quit
(d) MPEG4/PCM(24 bit) transcode
vlc -I dummy "Mr_MrsSmith-h264_aac.mp4" :sout="#transcode{vcodec=mp4v,vb=1024,fps=25,acodec=s24l}:standard{mux=avi,access=file,dst=out.avi}" vlc://quit
(e) MPEG4/PCM(32bit) transcode
vlc -I dummy "Mr_MrsSmith-h264_aac.mp4" :sout="#transcode{vcodec=mp4v,vb=1024,fps=25,acodec=s32l}:standard{mux=avi,access=file,dst=out.avi}" vlc://quit
(f) MJPEG/PCM(32bit) transcode
vlc -I dummy "Mr_MrsSmith-h264_aac.mp4" :sout="#transcode{vcodec=mjpeg,vb=1024,fps=25,acodec=s32l}:standard{mux=avi,access=file,dst=out.avi}" vlc://quit
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=1e6d1f3cb3d0ee4b36a939b17eb3a1de2131d34d
---
modules/mux/avi.c | 48 ++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 40 insertions(+), 8 deletions(-)
diff --git a/modules/mux/avi.c b/modules/mux/avi.c
index 0d2c4b6..d2d1a70 100644
--- a/modules/mux/avi.c
+++ b/modules/mux/avi.c
@@ -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;
@@ -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(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 )
{
@@ -819,7 +847,12 @@ 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 );
@@ -843,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 );
More information about the vlc-commits
mailing list