]> git.sesse.net Git - vlc/blobdiff - modules/codec/araw.c
fixed another possible crash
[vlc] / modules / codec / araw.c
index c72a3e6aee7ea703a2d71fd7068a3e607405fe54..f0b886fb529cff6834b47a3cb8b87eee62a59d83 100644 (file)
@@ -2,7 +2,7 @@
  * araw.c: Pseudo audio decoder; for raw pcm data
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: araw.c,v 1.2 2002/10/20 17:44:17 fenrir Exp $
+ * $Id: araw.c,v 1.11 2003/01/07 21:49:01 fenrir Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *      
 
 #include <stdlib.h>                                      /* malloc(), free() */
 #include <string.h>                                              /* strdup() */
-
+#include "codecs.h"
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-typedef struct waveformatex_s
-{
-    u16 i_formattag;
-    u16 i_channels;
-    u32 i_samplespersec;
-    u32 i_avgbytespersec;
-    u16 i_blockalign;
-    u16 i_bitspersample;
-    u16 i_size; /* the extra size in bytes */
-    u8  *p_data; /* The extra data */
-} waveformatex_t;
 
 typedef struct adec_thread_s
 {
-    waveformatex_t  format;
+    WAVEFORMATEX    *p_wf;
+    
+    //waveformatex_t  format;
 
     /* The bit stream structure handles the PES stream at the bit level */
-    bit_stream_t        bit_stream;
+//    bit_stream_t        bit_stream;
 
     /* Input properties */
     decoder_fifo_t *p_fifo;
@@ -85,12 +76,15 @@ vlc_module_begin();
 vlc_module_end();
 
 
-static int i_channels_maps[6] =
+static int pi_channels_maps[6] =
 {
     0,
-    AOUT_CHAN_MONO,     AOUT_CHAN_STEREO,
-    AOUT_CHAN_3F,       AOUT_CHAN_2F2R,
-    AOUT_CHAN_3F2R
+    AOUT_CHAN_CENTER,
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT,
+    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+     | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT 
 };
 
 /*****************************************************************************
@@ -168,7 +162,8 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
 #define GetDWLE( p ) \
     (  *(u8*)(p) + ( *((u8*)(p)+1) << 8 ) + \
         ( *((u8*)(p)+2) << 16 ) + ( *((u8*)(p)+3) << 24 ) )
-    
+
+#if 0
 static void GetWaveFormatEx( waveformatex_t *p_wh,
                              u8 *p_data )
 {
@@ -190,48 +185,7 @@ static void GetWaveFormatEx( waveformatex_t *p_wh,
         }
     }
 }
-
-/* get the first pes from fifo */
-static pes_packet_t *PESGetFirst( decoder_fifo_t *p_fifo )
-{
-    pes_packet_t *p_pes;
-
-    vlc_mutex_lock( &p_fifo->data_lock );
-
-    /* if fifo is empty wait */ 
-    while( !p_fifo->p_first )
-    {
-        if( p_fifo->b_die )
-        {
-            vlc_mutex_unlock( &p_fifo->data_lock );
-            return NULL;
-        }
-        vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
-    }
-    p_pes = p_fifo->p_first;
-
-    vlc_mutex_unlock( &p_fifo->data_lock );
-
-    return p_pes;
-}
-static int PESGetSize( pes_packet_t *p_pes )
-{
-    data_packet_t *p_data;
-    int i_size = 0;
-
-    if( !p_pes )
-    {
-        return( 0 );
-    }
-
-    for( p_data = p_pes->p_first; p_data != NULL; p_data = p_data->p_next )
-    {
-        i_size += p_data->p_payload_end - p_data->p_payload_start;
-    }
-
-    return( i_size );
-}
-
+#endif
 
 /*****************************************************************************
  * InitThread: initialize data before entering main loop
@@ -239,32 +193,30 @@ static int PESGetSize( pes_packet_t *p_pes )
 
 static int InitThread( adec_thread_t * p_adec )
 {
-
-    if( p_adec->p_fifo->p_demux_data )
-    {
-        GetWaveFormatEx( &p_adec->format,
-                         (u8*)p_adec->p_fifo->p_demux_data );
-        /* fixing some values */
-        if( p_adec->format.i_formattag == 1 && !p_adec->format.i_blockalign )
-        {
-            p_adec->format.i_blockalign = p_adec->format.i_channels * 
-                    ( ( p_adec->format.i_bitspersample + 7 ) / 8 );
-        }
-    }
-    else
+    if( ( p_adec->p_wf = (WAVEFORMATEX*)p_adec->p_fifo->p_waveformatex ) == NULL )
     {
         msg_Err( p_adec->p_fifo, "unknown raw format" );
         return( -1 );
     }
 
+    /* fixing some values */
+    if( p_adec->p_wf->wFormatTag  == WAVE_FORMAT_PCM && 
+        !p_adec->p_wf->nBlockAlign )
+    {
+        p_adec->p_wf->nBlockAlign = 
+            p_adec->p_wf->nChannels * 
+                ( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 );
+    }
+
     msg_Dbg( p_adec->p_fifo,
              "raw format: samplerate:%dHz channels:%d bits/sample:%d blockalign:%d",
-             p_adec->format.i_samplespersec,
-             p_adec->format.i_channels,
-             p_adec->format.i_bitspersample, p_adec->format.i_blockalign );
+             p_adec->p_wf->nSamplesPerSec,
+             p_adec->p_wf->nChannels,
+             p_adec->p_wf->wBitsPerSample, 
+             p_adec->p_wf->nBlockAlign );
 
     /* Initialize the thread properties */
-    switch( ( p_adec->format.i_bitspersample + 7 ) / 8 )
+    switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
     {
         case( 2 ):
             p_adec->output_format.i_format = VLC_FOURCC('s','1','6','l');
@@ -275,22 +227,25 @@ static int InitThread( adec_thread_t * p_adec )
         case( 4 ):
             p_adec->output_format.i_format = VLC_FOURCC('s','3','2','l');
             break;
-
         case( 1 ):
+            p_adec->output_format.i_format = VLC_FOURCC('u','8',' ',' ');
+            break;
         default:
             msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
             return( -1 );
     }
-    p_adec->output_format.i_rate = p_adec->format.i_samplespersec;
-    if( p_adec->output_format.i_channels <= 0 || 
-            p_adec->output_format.i_channels > 5 )
+    p_adec->output_format.i_rate = p_adec->p_wf->nSamplesPerSec;
+
+    if( p_adec->p_wf->nChannels <= 0 || 
+            p_adec->p_wf->nChannels > 5 )
     {
         msg_Err( p_adec->p_fifo, "bad channels count(1-5)" );
         return( -1 );
     }
 
-    p_adec->output_format.i_channels = 
-            i_channels_maps[p_adec->format.i_channels];
+    p_adec->output_format.i_physical_channels = 
+            p_adec->output_format.i_original_channels =
+            pi_channels_maps[p_adec->p_wf->nChannels];
     p_adec->p_aout = NULL;
     p_adec->p_aout_input = NULL;
 
@@ -306,12 +261,44 @@ static int InitThread( adec_thread_t * p_adec )
     }
 
     /* Init the BitStream */
-    InitBitstream( &p_adec->bit_stream, p_adec->p_fifo,
-                   NULL, NULL );
+//    InitBitstream( &p_adec->bit_stream, p_adec->p_fifo,
+//                   NULL, NULL );
 
     return( 0 );
 }
 
+static void GetPESData( u8 *p_buf, int i_max, pes_packet_t *p_pes )
+{
+    int i_copy;
+    int i_count;
+
+    data_packet_t   *p_data;
+
+    i_count = 0;
+    p_data = p_pes->p_first;
+    while( p_data != NULL && i_count < i_max )
+    {
+
+        i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start, i_max - i_count );
+        
+        if( i_copy > 0 )
+        {
+            memcpy( p_buf,
+                    p_data->p_payload_start,
+                    i_copy );
+        }
+
+        p_data = p_data->p_next;
+        i_count += i_copy;
+        p_buf   += i_copy;
+    }
+
+    if( i_count < i_max )
+    {
+        memset( p_buf, 0, i_max - i_count );
+    }
+}
+
 /*****************************************************************************
  * DecodeThread: decodes a frame
  *****************************************************************************/
@@ -320,17 +307,23 @@ static void DecodeThread( adec_thread_t *p_adec )
     aout_buffer_t   *p_aout_buffer;
     int             i_samples; // per channels
     int             i_size;
+
     pes_packet_t    *p_pes;
 
     /* **** get samples count **** */
-    p_pes = PESGetFirst( p_adec->p_fifo );
-    
-    i_size = PESGetSize( p_pes );
-    if( p_adec->format.i_blockalign > 0 )
+    input_ExtractPES( p_adec->p_fifo, &p_pes );
+    if( !p_pes )
+    {
+        p_adec->p_fifo->b_error = 1;
+        return;
+    }
+    i_size = p_pes->i_pes_size;
+
+    if( p_adec->p_wf->nBlockAlign > 0 )
     {
-        i_size -= i_size % p_adec->format.i_blockalign;
+        i_size -= i_size % p_adec->p_wf->nBlockAlign;
     }
-    i_size = __MAX( i_size, p_adec->format.i_blockalign );
+    i_size = __MAX( i_size, p_adec->p_wf->nBlockAlign );
 
     if( !i_size || !p_pes )
     {
@@ -338,8 +331,8 @@ static void DecodeThread( adec_thread_t *p_adec )
         return;
     }
     i_samples = i_size / 
-                ( ( p_adec->format.i_bitspersample + 7 ) / 8 ) / 
-                p_adec->format.i_channels;
+                ( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 ) / 
+                p_adec->p_wf->nChannels;
 
 //    msg_Warn( p_adec->p_fifo, "got %d samples (%d bytes)", i_samples, i_size );
     p_adec->pts = p_pes->i_pts;
@@ -368,11 +361,13 @@ static void DecodeThread( adec_thread_t *p_adec )
     p_aout_buffer->start_date = aout_DateGet( &p_adec->date );
     p_aout_buffer->end_date = aout_DateIncrement( &p_adec->date,
                                                   i_samples );
-    GetChunk( &p_adec->bit_stream,
-              p_aout_buffer->p_buffer,
-              p_aout_buffer->i_nb_bytes );
+
+    GetPESData( p_aout_buffer->p_buffer, p_aout_buffer->i_nb_bytes, p_pes );
 
     aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
+
+
+    input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
 }
 
 
@@ -386,8 +381,6 @@ static void EndThread (adec_thread_t *p_adec)
         aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
     }
 
-    FREE( p_adec->format.p_data );
-
     msg_Dbg( p_adec->p_fifo, "raw audio decoder closed" );
         
     free( p_adec );