Commit 35faa7ef authored by Laurent Aimar's avatar Laurent Aimar

* asf: prevent some segfault with broken file. (partially fix bug 72)

 * avi: respect frame size (for audio codec) and close bug 75.
 * ffmpeg: can now read multiples audio frames from the same buffer.
parent 18a6b179
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* audio.c: audio decoder using ffmpeg library * audio.c: audio decoder using ffmpeg library
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: audio.c,v 1.11 2003/01/07 21:49:01 fenrir Exp $ * $Id: audio.c,v 1.12 2003/01/11 18:10:49 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -135,7 +135,7 @@ int E_( InitThread_Audio )( adec_thread_t *p_adec ) ...@@ -135,7 +135,7 @@ int E_( InitThread_Audio )( adec_thread_t *p_adec )
p_adec->p_context->block_align = p_adec->format.i_blockalign; p_adec->p_context->block_align = p_adec->format.i_blockalign;
#endif #endif
p_adec->p_context->bit_rate = p_adec->format.i_avgbytespersec * 8; p_adec->p_context->bit_rate = p_adec->format.i_avgbytespersec * 8;
if( ( p_adec->p_context->extradata_size = p_adec->format.i_size ) > 0 ) if( ( p_adec->p_context->extradata_size = p_adec->format.i_size ) > 0 )
{ {
p_adec->p_context->extradata = p_adec->p_context->extradata =
...@@ -145,34 +145,34 @@ int E_( InitThread_Audio )( adec_thread_t *p_adec ) ...@@ -145,34 +145,34 @@ int E_( InitThread_Audio )( adec_thread_t *p_adec )
p_adec->format.p_data, p_adec->format.p_data,
p_adec->format.i_size ); p_adec->format.i_size );
} }
/* ***** Open the codec ***** */ /* ***** Open the codec ***** */
if (avcodec_open(p_adec->p_context, p_adec->p_codec) < 0) if (avcodec_open(p_adec->p_context, p_adec->p_codec) < 0)
{ {
msg_Err( p_adec->p_fifo, msg_Err( p_adec->p_fifo,
"cannot open codec (%s)", "cannot open codec (%s)",
p_adec->psz_namecodec ); p_adec->psz_namecodec );
return( -1 ); return( -1 );
} }
else else
{ {
msg_Dbg( p_adec->p_fifo, msg_Dbg( p_adec->p_fifo,
"ffmpeg codec (%s) started", "ffmpeg codec (%s) started",
p_adec->psz_namecodec ); p_adec->psz_namecodec );
} }
p_adec->p_output = malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE ); p_adec->p_output = malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE );
p_adec->output_format.i_format = AOUT_FMT_S16_NE; p_adec->output_format.i_format = AOUT_FMT_S16_NE;
p_adec->output_format.i_rate = p_adec->format.i_samplespersec; p_adec->output_format.i_rate = p_adec->format.i_samplespersec;
p_adec->output_format.i_physical_channels p_adec->output_format.i_physical_channels
= p_adec->output_format.i_original_channels = p_adec->output_format.i_original_channels
= p_adec->format.i_nb_channels; = p_adec->format.i_nb_channels;
p_adec->p_aout = NULL; p_adec->p_aout = NULL;
p_adec->p_aout_input = NULL; p_adec->p_aout_input = NULL;
return( 0 ); return( 0 );
} }
...@@ -188,7 +188,7 @@ void E_( DecodeThread_Audio )( adec_thread_t *p_adec ) ...@@ -188,7 +188,7 @@ void E_( DecodeThread_Audio )( adec_thread_t *p_adec )
int i_samplesperchannel; int i_samplesperchannel;
int i_output_size; int i_output_size;
int i_frame_size; int i_frame_size;
int i_status; int i_used;
do do
{ {
...@@ -203,32 +203,67 @@ void E_( DecodeThread_Audio )( adec_thread_t *p_adec ) ...@@ -203,32 +203,67 @@ void E_( DecodeThread_Audio )( adec_thread_t *p_adec )
if( i_frame_size > 0 ) if( i_frame_size > 0 )
{ {
if( p_adec->i_buffer_size < i_frame_size + 16 ) uint8_t *p_last;
int i_need;
i_need = i_frame_size + 16 + p_adec->i_buffer;
if( p_adec->i_buffer_size < i_need )
{ {
FREE( p_adec->p_buffer ); p_last = p_adec->p_buffer;
p_adec->p_buffer = malloc( i_frame_size + 16 ); p_adec->p_buffer = malloc( i_need );
p_adec->i_buffer_size = i_frame_size + 16; p_adec->i_buffer_size = i_need;
if( p_adec->i_buffer > 0 )
{
memcpy( p_adec->p_buffer, p_last, p_adec->i_buffer );
}
FREE( p_last );
} }
i_frame_size =
E_( GetPESData )( p_adec->p_buffer, p_adec->i_buffer_size, p_pes ); E_( GetPESData )( p_adec->p_buffer + p_adec->i_buffer,
i_frame_size,
p_pes );
/* make ffmpeg happier but I'm not sure it's needed for audio */
memset( p_adec->p_buffer + p_adec->i_buffer + i_frame_size,
0,
16 );
} }
input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes ); input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
} while( i_frame_size <= 0 ); } while( i_frame_size <= 0 );
i_status = avcodec_decode_audio( p_adec->p_context,
(s16*)p_adec->p_output, i_frame_size += p_adec->i_buffer;
&i_output_size,
p_adec->p_buffer, usenextdata:
i_frame_size ); i_used = avcodec_decode_audio( p_adec->p_context,
if( i_status < 0 ) (int16_t*)p_adec->p_output,
&i_output_size,
p_adec->p_buffer,
i_frame_size );
if( i_used < 0 )
{ {
msg_Warn( p_adec->p_fifo, msg_Warn( p_adec->p_fifo,
"cannot decode one frame (%d bytes)", "cannot decode one frame (%d bytes)",
i_frame_size ); i_frame_size );
p_adec->i_buffer = 0;
return; return;
} }
else if( i_used < i_frame_size )
{
memmove( p_adec->p_buffer,
p_adec->p_buffer + i_used,
p_adec->i_buffer_size - i_used );
p_adec->i_buffer = i_frame_size - i_used;
}
else
{
p_adec->i_buffer = 0;
}
i_frame_size -= i_used;
// msg_Dbg( p_adec->p_fifo, "frame size:%d buffer used:%d", i_frame_size, i_used );
if( i_output_size <= 0 ) if( i_output_size <= 0 )
{ {
msg_Warn( p_adec->p_fifo, msg_Warn( p_adec->p_fifo,
...@@ -274,7 +309,7 @@ void E_( DecodeThread_Audio )( adec_thread_t *p_adec ) ...@@ -274,7 +309,7 @@ void E_( DecodeThread_Audio )( adec_thread_t *p_adec )
msg_Err( p_adec->p_fifo, "cannot create aout" ); msg_Err( p_adec->p_fifo, "cannot create aout" );
return; return;
} }
if( p_adec->pts != 0 && p_adec->pts != aout_DateGet( &p_adec->date ) ) if( p_adec->pts != 0 && p_adec->pts != aout_DateGet( &p_adec->date ) )
{ {
aout_DateSet( &p_adec->date, p_adec->pts ); aout_DateSet( &p_adec->date, p_adec->pts );
...@@ -302,7 +337,12 @@ void E_( DecodeThread_Audio )( adec_thread_t *p_adec ) ...@@ -302,7 +337,12 @@ void E_( DecodeThread_Audio )( adec_thread_t *p_adec )
p_aout_buffer->i_nb_bytes ); p_aout_buffer->i_nb_bytes );
aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer ); aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
if( i_frame_size > 0 )
{
goto usenextdata;
}
return; return;
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* asf.c : ASFv01 file input module for vlc * asf.c : ASFv01 file input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: asf.c,v 1.14 2003/01/07 21:49:01 fenrir Exp $ * $Id: asf.c,v 1.15 2003/01/11 18:10:49 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -566,6 +566,12 @@ static int Demux( input_thread_t *p_input ) ...@@ -566,6 +566,12 @@ static int Demux( input_thread_t *p_input )
mtime_t i_pts; mtime_t i_pts;
mtime_t i_pts_delta; mtime_t i_pts_delta;
if( i_skip >= i_packet_size_left )
{
/* prevent some segfault with invalid file */
break;
}
i_stream_number = p_peek[i_skip] & 0x7f; i_stream_number = p_peek[i_skip] & 0x7f;
i_skip++; i_skip++;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* avi.c : AVI file Stream input module for vlc * avi.c : AVI file Stream input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: avi.c,v 1.21 2003/01/09 18:23:43 fenrir Exp $ * $Id: avi.c,v 1.22 2003/01/11 18:10:49 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -139,7 +139,7 @@ static int input_ReadInPES( input_thread_t *p_input, ...@@ -139,7 +139,7 @@ static int input_ReadInPES( input_thread_t *p_input,
i_read = input_SplitBuffer(p_input, i_read = input_SplitBuffer(p_input,
&p_data, &p_data,
__MIN( i_size - __MIN( i_size -
p_pes->i_pes_size, 1024 ) ); p_pes->i_pes_size, 2048 ) );
if( i_read <= 0 ) if( i_read <= 0 )
{ {
return p_pes->i_pes_size; return p_pes->i_pes_size;
...@@ -1083,12 +1083,6 @@ static int AVIInit( vlc_object_t * p_this ) ...@@ -1083,12 +1083,6 @@ static int AVIInit( vlc_object_t * p_this )
} }
/* *** movie length in sec *** */ /* *** movie length in sec *** */
#if 0
p_avi->i_length = (mtime_t)p_avih->i_totalframes *
(mtime_t)p_avih->i_microsecperframe /
(mtime_t)1000000;
#endif
p_avi->i_length = AVI_MovieGetLength( p_input, p_avi ); p_avi->i_length = AVI_MovieGetLength( p_input, p_avi );
if( p_avi->i_length < (mtime_t)p_avih->i_totalframes * if( p_avi->i_length < (mtime_t)p_avih->i_totalframes *
(mtime_t)p_avih->i_microsecperframe / (mtime_t)p_avih->i_microsecperframe /
...@@ -1183,11 +1177,10 @@ static inline mtime_t AVI_PTSToByte( avi_stream_t *p_info, ...@@ -1183,11 +1177,10 @@ static inline mtime_t AVI_PTSToByte( avi_stream_t *p_info,
mtime_t i_pts ) mtime_t i_pts )
{ {
return (mtime_t)((int64_t)i_pts * return (mtime_t)((int64_t)i_pts *
(int64_t)p_info->i_samplesize *
(int64_t)p_info->i_rate / (int64_t)p_info->i_rate /
(int64_t)p_info->i_scale / (int64_t)p_info->i_scale /
(int64_t)1000000 ); (int64_t)1000000 *
(int64_t)p_info->i_samplesize );
} }
static mtime_t AVI_GetDPTS( avi_stream_t *p_stream, int i_count ) static mtime_t AVI_GetDPTS( avi_stream_t *p_stream, int i_count )
...@@ -1610,6 +1603,44 @@ static int AVISeek ( input_thread_t *p_input, ...@@ -1610,6 +1603,44 @@ static int AVISeek ( input_thread_t *p_input,
} }
} }
#if 0
static pes_packet_t *PES_split( input_thread_t *p_input, avi_stream_t *p_stream, pes_packet_t *p_pes )
{
pes_packet_t *p_pes2;
data_packet_t *p_data;
int i_nb_data;
if( p_pes->i_nb_data < 2 )
{
return( NULL );
}
p_pes2 = input_NewPES( p_input->p_method_data );
p_pes2->i_pts = p_pes->i_pts;
p_pes2->i_dts = p_pes->i_dts;
p_pes2->i_nb_data = p_pes->i_nb_data/2;
p_pes2->i_pes_size = 0;
for( i_nb_data = 0, p_data = p_pes->p_first;
i_nb_data < p_pes2->i_nb_data;
i_nb_data++, p_data = p_data->p_next )
{
p_pes2->i_pes_size +=
p_data->p_payload_end - p_data->p_payload_start;
p_pes2->p_last = p_data;
}
p_pes2->p_first = p_pes->p_first;
p_pes2->p_last->p_next = NULL;
p_pes->p_first = p_data;
p_pes->i_pes_size -= p_pes2->i_pes_size;
p_pes->i_nb_data -= p_pes2->i_nb_data;
// p_pes->i_pts += AVI_GetDPTS( p_stream, p_pes2->i_pes_size );
// p_pes->i_dts += AVI_GetDPTS( p_stream, p_pes2->i_pes_size );
p_pes->i_pts = 0;
p_pes->i_dts = 0;
return( p_pes2 );
}
#endif
/***************************************************************************** /*****************************************************************************
* AVIDemux_Seekable: reads and demuxes data packets for stream seekable * AVIDemux_Seekable: reads and demuxes data packets for stream seekable
***************************************************************************** *****************************************************************************
...@@ -1871,9 +1902,8 @@ static int AVIDemux_Seekable( input_thread_t *p_input ) ...@@ -1871,9 +1902,8 @@ static int AVIDemux_Seekable( input_thread_t *p_input )
{ {
i_size = __MIN( p_stream->p_index[p_stream->i_idxposc].i_length - i_size = __MIN( p_stream->p_index[p_stream->i_idxposc].i_length -
p_stream->i_idxposb, p_stream->i_idxposb,
// 100 * 1024 ); // 10Ko max __MAX( toread[i_stream].i_toread,
__MAX( toread[i_stream].i_toread, 128 ) ); p_stream->i_samplesize ) );
// 128 is to avoid infinit loop
} }
else else
{ {
...@@ -1952,7 +1982,28 @@ static int AVIDemux_Seekable( input_thread_t *p_input ) ...@@ -1952,7 +1982,28 @@ static int AVIDemux_Seekable( input_thread_t *p_input )
input_ClockGetTS( p_input, input_ClockGetTS( p_input,
p_input->stream.p_selected_program, p_input->stream.p_selected_program,
p_pes->i_pts * 9/100); p_pes->i_pts * 9/100);
#if 0
/* debuuging: split pes in 2 parts */
if( p_pes->i_nb_data >= 2 && p_stream->i_cat == AUDIO_ES )
{
pes_packet_t *p_pes_;
data_packet_t *p_data;
int i_nb_data;
p_pes_ = PES_split( p_input, p_stream, p_pes );
if( p_pes_->i_nb_data >= 2 )
{
input_DecodePES( p_stream->p_es->p_decoder_fifo, PES_split( p_input,p_stream,p_pes_ ) );
}
input_DecodePES( p_stream->p_es->p_decoder_fifo,p_pes_ );
if( p_pes->i_nb_data >= 2 )
{
input_DecodePES( p_stream->p_es->p_decoder_fifo, PES_split( p_input,p_stream,p_pes ) );
}
//input_DecodePES( p_stream->p_es->p_decoder_fifo,p_pes );
}
#endif
input_DecodePES( p_stream->p_es->p_decoder_fifo, p_pes ); input_DecodePES( p_stream->p_es->p_decoder_fifo, p_pes );
} }
else else
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* libavi.c : * libavi.c :
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: libavi.c,v 1.12 2002/12/18 16:16:30 sam Exp $ * $Id: libavi.c,v 1.13 2003/01/11 18:10:49 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -546,7 +546,7 @@ static int AVI_ChunkRead_strf( input_thread_t *p_input, ...@@ -546,7 +546,7 @@ static int AVI_ChunkRead_strf( input_thread_t *p_input,
if( p_chk->strf.auds.p_wf->cbSize > 0 ) if( p_chk->strf.auds.p_wf->cbSize > 0 )
{ {
memcpy( &p_chk->strf.auds.p_wf[1] , memcpy( &p_chk->strf.auds.p_wf[1] ,
p_buff + sizeof( WAVEFORMATEX ), p_buff + 8 + sizeof( WAVEFORMATEX ), // 8=fourrc+size
p_chk->strf.auds.p_wf->cbSize ); p_chk->strf.auds.p_wf->cbSize );
} }
#ifdef AVI_DEBUG #ifdef AVI_DEBUG
...@@ -581,7 +581,7 @@ static int AVI_ChunkRead_strf( input_thread_t *p_input, ...@@ -581,7 +581,7 @@ static int AVI_ChunkRead_strf( input_thread_t *p_input,
if( p_chk->strf.vids.p_bih->biSize - sizeof(BITMAPINFOHEADER) > 0 ) if( p_chk->strf.vids.p_bih->biSize - sizeof(BITMAPINFOHEADER) > 0 )
{ {
memcpy( &p_chk->strf.vids.p_bih[1], memcpy( &p_chk->strf.vids.p_bih[1],
p_buff + sizeof(BITMAPINFOHEADER), p_buff + 8 + sizeof(BITMAPINFOHEADER), // 8=fourrc+size
p_chk->strf.vids.p_bih->biSize - p_chk->strf.vids.p_bih->biSize -
sizeof(BITMAPINFOHEADER) ); sizeof(BITMAPINFOHEADER) );
} }
...@@ -614,7 +614,7 @@ static int AVI_ChunkRead_strd( input_thread_t *p_input, ...@@ -614,7 +614,7 @@ static int AVI_ChunkRead_strd( input_thread_t *p_input,
AVI_READCHUNK_ENTER; AVI_READCHUNK_ENTER;
p_chk->strd.p_data = malloc( p_chk->common.i_chunk_size ); p_chk->strd.p_data = malloc( p_chk->common.i_chunk_size );
memcpy( p_chk->strd.p_data, memcpy( p_chk->strd.p_data,
p_buff, p_buff + 8,
p_chk->common.i_chunk_size ); p_chk->common.i_chunk_size );
AVI_READCHUNK_EXIT( VLC_SUCCESS ); AVI_READCHUNK_EXIT( VLC_SUCCESS );
} }
......
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