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 @@
* audio.c: audio decoder using ffmpeg library
*****************************************************************************
* 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>
*
......@@ -135,7 +135,7 @@ int E_( InitThread_Audio )( adec_thread_t *p_adec )
p_adec->p_context->block_align = p_adec->format.i_blockalign;
#endif
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 )
{
p_adec->p_context->extradata =
......@@ -145,34 +145,34 @@ int E_( InitThread_Audio )( adec_thread_t *p_adec )
p_adec->format.p_data,
p_adec->format.i_size );
}
/* ***** Open the codec ***** */
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)",
p_adec->psz_namecodec );
return( -1 );
}
else
{
msg_Dbg( p_adec->p_fifo,
msg_Dbg( p_adec->p_fifo,
"ffmpeg codec (%s) started",
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_rate = p_adec->format.i_samplespersec;
p_adec->output_format.i_physical_channels
= p_adec->output_format.i_original_channels
= p_adec->format.i_nb_channels;
p_adec->p_aout = NULL;
p_adec->p_aout_input = NULL;
return( 0 );
}
......@@ -188,7 +188,7 @@ void E_( DecodeThread_Audio )( adec_thread_t *p_adec )
int i_samplesperchannel;
int i_output_size;
int i_frame_size;
int i_status;
int i_used;
do
{
......@@ -203,32 +203,67 @@ void E_( DecodeThread_Audio )( adec_thread_t *p_adec )
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_adec->p_buffer = malloc( i_frame_size + 16 );
p_adec->i_buffer_size = i_frame_size + 16;
p_last = p_adec->p_buffer;
p_adec->p_buffer = malloc( i_need );
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 );
}
E_( GetPESData )( p_adec->p_buffer, p_adec->i_buffer_size, p_pes );
i_frame_size =
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 );
} while( i_frame_size <= 0 );
i_status = avcodec_decode_audio( p_adec->p_context,
(s16*)p_adec->p_output,
&i_output_size,
p_adec->p_buffer,
i_frame_size );
if( i_status < 0 )
i_frame_size += p_adec->i_buffer;
usenextdata:
i_used = avcodec_decode_audio( p_adec->p_context,
(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)",
i_frame_size );
p_adec->i_buffer = 0;
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 )
{
msg_Warn( p_adec->p_fifo,
......@@ -274,7 +309,7 @@ void E_( DecodeThread_Audio )( adec_thread_t *p_adec )
msg_Err( p_adec->p_fifo, "cannot create aout" );
return;
}
if( p_adec->pts != 0 && p_adec->pts != aout_DateGet( &p_adec->date ) )
{
aout_DateSet( &p_adec->date, p_adec->pts );
......@@ -302,7 +337,12 @@ void E_( DecodeThread_Audio )( adec_thread_t *p_adec )
p_aout_buffer->i_nb_bytes );
aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
if( i_frame_size > 0 )
{
goto usenextdata;
}
return;
}
......
......@@ -2,7 +2,7 @@
* asf.c : ASFv01 file input module for vlc
*****************************************************************************
* 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>
*
* This program is free software; you can redistribute it and/or modify
......@@ -566,6 +566,12 @@ static int Demux( input_thread_t *p_input )
mtime_t i_pts;
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_skip++;
......
......@@ -2,7 +2,7 @@
* avi.c : AVI file Stream input module for vlc
*****************************************************************************
* 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>
*
* 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,
i_read = input_SplitBuffer(p_input,
&p_data,
__MIN( i_size -
p_pes->i_pes_size, 1024 ) );
p_pes->i_pes_size, 2048 ) );
if( i_read <= 0 )
{
return p_pes->i_pes_size;
......@@ -1083,12 +1083,6 @@ static int AVIInit( vlc_object_t * p_this )
}
/* *** 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 );
if( p_avi->i_length < (mtime_t)p_avih->i_totalframes *
(mtime_t)p_avih->i_microsecperframe /
......@@ -1183,11 +1177,10 @@ static inline mtime_t AVI_PTSToByte( avi_stream_t *p_info,
mtime_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_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 )
......@@ -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
*****************************************************************************
......@@ -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 -
p_stream->i_idxposb,
// 100 * 1024 ); // 10Ko max
__MAX( toread[i_stream].i_toread, 128 ) );
// 128 is to avoid infinit loop
__MAX( toread[i_stream].i_toread,
p_stream->i_samplesize ) );
}
else
{
......@@ -1952,7 +1982,28 @@ static int AVIDemux_Seekable( input_thread_t *p_input )
input_ClockGetTS( p_input,
p_input->stream.p_selected_program,
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 );
}
else
......
......@@ -2,7 +2,7 @@
* libavi.c :
*****************************************************************************
* 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>
*
* 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,
if( p_chk->strf.auds.p_wf->cbSize > 0 )
{
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 );
}
#ifdef AVI_DEBUG
......@@ -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 )
{
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 -
sizeof(BITMAPINFOHEADER) );
}
......@@ -614,7 +614,7 @@ static int AVI_ChunkRead_strd( input_thread_t *p_input,
AVI_READCHUNK_ENTER;
p_chk->strd.p_data = malloc( p_chk->common.i_chunk_size );
memcpy( p_chk->strd.p_data,
p_buff,
p_buff + 8,
p_chk->common.i_chunk_size );
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