* asf: prevent some segfault with broken file. (partially fix bug 72)
authorLaurent Aimar <fenrir@videolan.org>
Sat, 11 Jan 2003 18:10:49 +0000 (18:10 +0000)
committerLaurent Aimar <fenrir@videolan.org>
Sat, 11 Jan 2003 18:10:49 +0000 (18:10 +0000)
 * avi: respect frame size (for audio codec) and close bug 75.
 * ffmpeg: can now read multiples audio frames from the same buffer.

modules/codec/ffmpeg/audio.c
modules/demux/asf/asf.c
modules/demux/avi/avi.c
modules/demux/avi/libavi.c

index 55cd530..835d5b8 100644 (file)
@@ -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;
 }
 
index 2c4c604..b2c3144 100644 (file)
@@ -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++;
 
index 880b3a3..0ec5806 100644 (file)
@@ -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
index 553bae8..3f2661e 100644 (file)
@@ -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 );
 }