]> git.sesse.net Git - vlc/blobdiff - src/audio_decoder/audio_decoder.c
* Mandatory step for video output IV and the audio output quality
[vlc] / src / audio_decoder / audio_decoder.c
index 323be13c33d68f25bd55dd2f0e70128b6d65064a..763c3aac829147ed700dd8a3697dec787ee7a27b 100644 (file)
 /*****************************************************************************
- * audio_decoder.c: MPEG1 Layer I-II audio decoder
+ * audio_decoder.c: MPEG audio decoder thread
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
+ * $Id: audio_decoder.c,v 1.50 2001/05/01 04:18:18 sam Exp $
  *
- * Authors:
+ * Authors: Michel Kaempf <maxx@via.ecp.fr>
+ *          Michel Lespinasse <walken@via.ecp.fr>
+ *          Samuel Hocevar <sam@via.ecp.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- *
+ * 
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
 /*
  * TODO :
  *
  * - optimiser les NeedBits() et les GetBits() du code là où c'est possible ;
+ * - vlc_cond_signal() / vlc_cond_wait() ;
  *
  */
 
-#include "int_types.h"
-#include "audio_constants.h"
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <unistd.h>                                              /* getpid() */
+
+#include <stdio.h>                                           /* "intf_msg.h" */
+#include <string.h>                                    /* memcpy(), memset() */
+#include <stdlib.h>                                      /* malloc(), free() */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+
+#include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
+#include "stream_control.h"
+#include "input_ext-dec.h"
+
+#include "audio_output.h"               /* aout_fifo_t (for audio_decoder.h) */
+
+#include "adec_generic.h"
 #include "audio_decoder.h"
-#include "audio_math.h"                                    /* DCT32(), PCM() */
-#include "audio_bit_stream.h"
+#include "adec_math.h"                                     /* DCT32(), PCM() */
 
-#define NULL ((void *)0)
+#define ADEC_FRAME_SIZE (2*1152)
 
 /*****************************************************************************
- * adec_Layer`L'_`M': decodes an mpeg 1, layer `L', mode `M', audio frame
- *****************************************************************************
- * These functions decode the audio frame which has already its header loaded
- * in the i_header member of the audio decoder thread structure and its first
- * byte of data described by the bit stream structure of the audio decoder
- * thread (there is no bit available in the bit buffer yet)
+ * Local prototypes
  *****************************************************************************/
+static int      InitThread             (adec_thread_t * p_adec);
+static void     RunThread              (adec_thread_t * p_adec);
+static void     ErrorThread            (adec_thread_t * p_adec);
+static void     EndThread              (adec_thread_t * p_adec);
 
 /*****************************************************************************
- * adec_Layer1_Mono
+ * adec_CreateThread: creates an audio decoder thread
+ *****************************************************************************
+ * This function creates a new audio decoder thread, and returns a pointer to
+ * its description. On error, it returns NULL.
  *****************************************************************************/
-static __inline__ int adec_Layer1_Mono (audiodec_t * p_adec)
+vlc_thread_t adec_CreateThread ( adec_config_t * p_config )
 {
-    p_adec->bit_stream.buffer = 0;
-    p_adec->bit_stream.i_available = 0;
-    return (0);
-}
+    adec_thread_t *     p_adec;
 
-/*****************************************************************************
- * adec_Layer1_Stereo
- *****************************************************************************/
-static __inline__ int adec_Layer1_Stereo (audiodec_t * p_adec)
-{
-    p_adec->bit_stream.buffer = 0;
-    p_adec->bit_stream.i_available = 0;
-    return (0);
-}
+    intf_DbgMsg ( "adec debug: creating audio decoder thread" );
 
-/*****************************************************************************
- * adec_Layer2_Mono
- *****************************************************************************/
-static __inline__ int adec_Layer2_Mono (audiodec_t * p_adec)
-{
-    p_adec->bit_stream.buffer = 0;
-    p_adec->bit_stream.i_available = 0;
-    return (0);
+    /* Allocate the memory needed to store the thread's structure */
+    if ( (p_adec = (adec_thread_t *)malloc (sizeof(adec_thread_t))) == NULL ) 
+    {
+        intf_ErrMsg ( "adec error: not enough memory for"
+                      " adec_CreateThread() to create the new thread" );
+        return 0;
+    }
+
+    /*
+     * Initialize the thread properties
+     */
+    p_adec->p_config = p_config;
+    p_adec->p_fifo = p_config->decoder_config.p_decoder_fifo;
+
+    /*
+     * Initialize the decoder properties
+     */
+    adec_Init ( p_adec );
+
+    /*
+     * Initialize the output properties
+     */
+    p_adec->p_aout_fifo = NULL;
+
+    /* Spawn the audio decoder thread */
+    if ( vlc_thread_create(&p_adec->thread_id, "audio decoder",
+         (vlc_thread_func_t)RunThread, (void *)p_adec) ) 
+    {
+        intf_ErrMsg ("adec error: can't spawn audio decoder thread");
+        free (p_adec);
+        return 0;
+    }
+
+    intf_DbgMsg ("adec debug: audio decoder thread (%p) created", p_adec);
+    return p_adec->thread_id;
 }
 
+/* following functions are local */
+
 /*****************************************************************************
- * adec_Layer2_Stereo
+ * InitThread : initialize an audio decoder thread
+ *****************************************************************************
+ * This function is called from RunThread and performs the second step of the
+ * initialization. It returns 0 on success.
  *****************************************************************************/
-static __inline__ int adec_Layer2_Stereo (audiodec_t * p_adec, s16 * buffer)
+static int InitThread (adec_thread_t * p_adec)
 {
-    typedef struct requantization_s
-    {
-        u8                              i_bits_per_codeword;
-        const float *                   pf_ungroup;
-        float                           f_slope;
-        float                           f_offset;
-    } requantization_t;
-
-    static const float                  pf_scalefactor[64] = ADEC_SCALE_FACTOR;
-
-    static u32                          i_header;
-    static int                          i_sampling_frequency, i_mode, i_bound;
-    static int                          pi_allocation_0[32], pi_allocation_1[32]; /* see ISO/IEC 11172-3 2.4.1.6 */
-    int                                 i_sb, i_nbal;
-    float                               f_scalefactor_0, f_scalefactor_1;
-
-    static const u8                     ppi_bitrate_per_channel_index[4][15] = ADEC_LAYER2_BITRATE_PER_CHANNEL_INDEX;
-    static const u8                     ppi_sblimit[3][11] = ADEC_LAYER2_SBLIMIT;
-    static const u8                     ppi_nbal[2][32] = ADEC_LAYER2_NBAL;
-
-    static const float                  pf_ungroup3[3*3*3 * 3] = ADEC_LAYER2_UNGROUP3;
-    static const float                  pf_ungroup5[5*5*5 * 3] = ADEC_LAYER2_UNGROUP5;
-    static const float                  pf_ungroup9[9*9*9 * 3] = ADEC_LAYER2_UNGROUP9;
-
-    static const requantization_t       p_requantization_cd[16] = ADEC_LAYER2_REQUANTIZATION_CD;
-    static const requantization_t       p_requantization_ab1[16] = ADEC_LAYER2_REQUANTIZATION_AB1;
-    static const requantization_t       p_requantization_ab2[16] = ADEC_LAYER2_REQUANTIZATION_AB2;
-    static const requantization_t       p_requantization_ab3[16] = ADEC_LAYER2_REQUANTIZATION_AB3;
-    static const requantization_t       p_requantization_ab4[16] = ADEC_LAYER2_REQUANTIZATION_AB4;
-    static const requantization_t *     pp_requantization_ab[30] = ADEC_LAYER2_REQUANTIZATION_AB;
-
-    static int                          i_sblimit, i_bitrate_per_channel_index;
-    static int                          pi_scfsi_0[30], pi_scfsi_1[30];
-    static const u8 *                   pi_nbal;
-    static float                        ppf_sample_0[3][32], ppf_sample_1[3][32];
-    static const requantization_t *     pp_requantization_0[30];
-    static const requantization_t *     pp_requantization_1[30];
-    static requantization_t             requantization;
-    static const float *                pf_ungroup;
-
-    static float                        pf_scalefactor_0_0[30], pf_scalefactor_0_1[30], pf_scalefactor_0_2[30];
-    static float                        pf_scalefactor_1_0[30], pf_scalefactor_1_1[30], pf_scalefactor_1_2[30];
-
-    int                                 i_2nbal, i_gr;
-    float                               f_dummy;
-
-    s16 *                               p_s16;
-
-    int                                 i_need = 0, i_dump = 0;
-#if 0
-    static const int                    pi_framesize[512] = ADEC_FRAME_SIZE;
-#endif
-
-    /* Read the audio frame header and flush the bit buffer */
-    i_header = p_adec->header;
-    /* Read the sampling frequency (see ISO/IEC 11172-3 2.4.2.3) */
-    i_sampling_frequency = (int)((i_header & ADEC_HEADER_SAMPLING_FREQUENCY_MASK)
-        >> ADEC_HEADER_SAMPLING_FREQUENCY_SHIFT);
-    /* Read the mode (see ISO/IEC 11172-3 2.4.2.3) */
-    i_mode = (int)((i_header & ADEC_HEADER_MODE_MASK) >> ADEC_HEADER_MODE_SHIFT);
-    /* If a CRC can be found in the frame, get rid of it */
-    if ((i_header & ADEC_HEADER_PROTECTION_BIT_MASK) == 0)
-    {
-        NeedBits (&p_adec->bit_stream, 16);
-        DumpBits (&p_adec->bit_stream, 16);
-    }
+    intf_DbgMsg ("adec debug: initializing audio decoder thread %p", p_adec);
 
-    /* Find out the bitrate per channel index */
-    i_bitrate_per_channel_index = (int)ppi_bitrate_per_channel_index[i_mode]
-        [(i_header & ADEC_HEADER_BITRATE_INDEX_MASK) >> ADEC_HEADER_BITRATE_INDEX_SHIFT];
-    /* Find out the number of subbands */
-    i_sblimit = (int)ppi_sblimit[i_sampling_frequency][i_bitrate_per_channel_index];
-    /* Check if the frame is valid or not */
-    if (i_sblimit == 0)
-    {
-        return (0);                                 /* the frame is invalid */
-    }
-    /* Find out the number of bits allocated */
-    pi_nbal = ppi_nbal[ (i_bitrate_per_channel_index <= 2) ? 0 : 1 ];
+    p_adec->p_config->decoder_config.pf_init_bit_stream( &p_adec->bit_stream,
+        p_adec->p_config->decoder_config.p_decoder_fifo, NULL, NULL );
 
-    /* Find out the `bound' subband (see ISO/IEC 11172-3 2.4.2.3) */
-    if (i_mode == 1)
+    /* Creating the audio output fifo */
+    p_adec->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 0, 0,
+                                           ADEC_FRAME_SIZE, NULL );
+    if ( p_adec->p_aout_fifo == NULL ) 
     {
-        i_bound = (int)(((i_header & ADEC_HEADER_MODE_EXTENSION_MASK) >> (ADEC_HEADER_MODE_EXTENSION_SHIFT - 2)) + 4);
-        if (i_bound > i_sblimit)
-        {
-            i_bound = i_sblimit;
-        }
-    }
-    else
-    {
-        i_bound = i_sblimit;
+        return -1;
     }
 
-    /* Read the allocation information (see ISO/IEC 11172-3 2.4.1.6) */
-    for (i_sb = 0; i_sb < i_bound; i_sb++)
-    {
-        i_2nbal = 2 * (i_nbal = (int)pi_nbal[ i_sb ]);
-        NeedBits (&p_adec->bit_stream, i_2nbal);
-        i_need += i_2nbal;
-        pi_allocation_0[ i_sb ] = (int)(p_adec->bit_stream.buffer >> (32 - i_nbal));
-        p_adec->bit_stream.buffer <<= i_nbal;
-        pi_allocation_1[ i_sb ] = (int)(p_adec->bit_stream.buffer >> (32 - i_nbal));
-        p_adec->bit_stream.buffer <<= i_nbal;
-        p_adec->bit_stream.i_available -= i_2nbal;
-        i_dump += i_2nbal;
-    }
-    for (; i_sb < i_sblimit; i_sb++)
-    {
-        i_nbal = (int)pi_nbal[ i_sb ];
-        NeedBits (&p_adec->bit_stream, i_nbal);
-        i_need += i_nbal;
-        pi_allocation_0[ i_sb ] = (int)(p_adec->bit_stream.buffer >> (32 - i_nbal));
-        DumpBits (&p_adec->bit_stream, i_nbal);
-        i_dump += i_nbal;
-    }
+    intf_DbgMsg ( "adec debug: audio decoder thread %p initialized", p_adec );
+    return 0;
+}
 
-#define MACRO(p_requantization) \
-    for (i_sb = 0; i_sb < i_bound; i_sb++) \
-    { \
-        if (pi_allocation_0[i_sb]) \
-        { \
-            pp_requantization_0[i_sb] = &((p_requantization)[pi_allocation_0[i_sb]]); \
-            NeedBits (&p_adec->bit_stream, 2); \
-            i_need += 2; \
-            pi_scfsi_0[i_sb] = (int)(p_adec->bit_stream.buffer >> (32 - 2)); \
-            DumpBits (&p_adec->bit_stream, 2); \
-            i_dump += 2; \
-        } \
-        else \
-        { \
-            ppf_sample_0[0][i_sb] = .0; \
-            ppf_sample_0[1][i_sb] = .0; \
-            ppf_sample_0[2][i_sb] = .0; \
-        } \
-\
-        if (pi_allocation_1[i_sb]) \
-        { \
-            pp_requantization_1[i_sb] = &((p_requantization)[pi_allocation_1[i_sb]]); \
-            NeedBits (&p_adec->bit_stream, 2); \
-            i_need += 2; \
-            pi_scfsi_1[i_sb] = (int)(p_adec->bit_stream.buffer >> (32 - 2)); \
-            DumpBits (&p_adec->bit_stream, 2); \
-            i_dump += 2; \
-        } \
-        else \
-        { \
-            ppf_sample_1[0][i_sb] = .0; \
-            ppf_sample_1[1][i_sb] = .0; \
-            ppf_sample_1[2][i_sb] = .0; \
-        } \
-    } \
-\
-    for (; i_sb < i_sblimit; i_sb++) \
-    { \
-        if (pi_allocation_0[i_sb]) \
-        { \
-            pp_requantization_0[i_sb] = &((p_requantization)[pi_allocation_0[i_sb]]); \
-            NeedBits (&p_adec->bit_stream, 4); \
-            i_need += 4; \
-            pi_scfsi_0[i_sb] = (int)(p_adec->bit_stream.buffer >> (32 - 2)); \
-            p_adec->bit_stream.buffer <<= 2; \
-            pi_scfsi_1[i_sb] = (int)(p_adec->bit_stream.buffer >> (32 - 2)); \
-            p_adec->bit_stream.buffer <<= 2; \
-            p_adec->bit_stream.i_available -= 4; \
-            i_dump += 4; \
-        } \
-        else \
-        { \
-            ppf_sample_0[0][i_sb] = .0; \
-            ppf_sample_0[1][i_sb] = .0; \
-            ppf_sample_0[2][i_sb] = .0; \
-            ppf_sample_1[0][i_sb] = .0; \
-            ppf_sample_1[1][i_sb] = .0; \
-            ppf_sample_1[2][i_sb] = .0; \
-        } \
-    }
-/* #define MACRO */
+/*****************************************************************************
+ * RunThread : audio decoder thread
+ *****************************************************************************
+ * Audio decoder thread. This function does only returns when the thread is
+ * terminated.
+ *****************************************************************************/
+static void RunThread (adec_thread_t * p_adec)
+{
+    int sync;
 
-    if (i_bitrate_per_channel_index <= 2)
-    {
-        MACRO (p_requantization_cd)
-    }
-    else
-    {
-        MACRO (pp_requantization_ab[i_sb])
-    }
+    intf_DbgMsg ( "adec debug: running audio decoder thread (%p) (pid == %i)",
+                  p_adec, getpid() );
 
-#define SWITCH(pi_scfsi,pf_scalefactor_0,pf_scalefactor_1,pf_scalefactor_2) \
-    switch ((pi_scfsi)[i_sb]) \
-    { \
-        case 0: \
-            NeedBits (&p_adec->bit_stream, (3*6)); \
-            i_need += 18; \
-           (pf_scalefactor_0)[i_sb] = pf_scalefactor[p_adec->bit_stream.buffer >> (32 - 6)]; \
-            p_adec->bit_stream.buffer <<= 6; \
-           (pf_scalefactor_1)[i_sb] = pf_scalefactor[p_adec->bit_stream.buffer >> (32 - 6)]; \
-            p_adec->bit_stream.buffer <<= 6; \
-           (pf_scalefactor_2)[i_sb] = pf_scalefactor[p_adec->bit_stream.buffer >> (32 - 6)]; \
-            p_adec->bit_stream.buffer <<= 6; \
-            p_adec->bit_stream.i_available -= (3*6); \
-            i_dump += 18; \
-            break; \
-\
-        case 1: \
-            NeedBits (&p_adec->bit_stream, (2*6)); \
-            i_need += 12; \
-           (pf_scalefactor_0)[i_sb] = \
-               (pf_scalefactor_1)[i_sb] = pf_scalefactor[p_adec->bit_stream.buffer >> (32 - 6)]; \
-            p_adec->bit_stream.buffer <<= 6; \
-           (pf_scalefactor_2)[i_sb] = pf_scalefactor[p_adec->bit_stream.buffer >> (32 - 6)]; \
-            p_adec->bit_stream.buffer <<= 6; \
-            p_adec->bit_stream.i_available -= (2*6); \
-            i_dump += 12; \
-            break; \
-\
-        case 2: \
-            NeedBits (&p_adec->bit_stream, (1*6)); \
-            i_need += 6; \
-           (pf_scalefactor_0)[i_sb] = \
-               (pf_scalefactor_1)[i_sb] = \
-               (pf_scalefactor_2)[i_sb] = pf_scalefactor[p_adec->bit_stream.buffer >> (32 - 6)]; \
-            DumpBits (&p_adec->bit_stream, (1*6)); \
-            i_dump += 6; \
-            break; \
-\
-        case 3: \
-            NeedBits (&p_adec->bit_stream, (2*6)); \
-            i_need += 12; \
-           (pf_scalefactor_0)[i_sb] = pf_scalefactor[p_adec->bit_stream.buffer >> (32 - 6)]; \
-            p_adec->bit_stream.buffer <<= 6; \
-           (pf_scalefactor_1)[i_sb] = \
-               (pf_scalefactor_2)[i_sb] = pf_scalefactor[p_adec->bit_stream.buffer >> (32 - 6)]; \
-            p_adec->bit_stream.buffer <<= 6; \
-            p_adec->bit_stream.i_available -= (2*6); \
-            i_dump += 12; \
-            break; \
-    }
-/* #define SWITCH */
+    /* Initializing the audio decoder thread */
+    p_adec->p_fifo->b_error = InitThread (p_adec);
+
+    sync = 0;
 
-    for (i_sb = 0; i_sb < i_bound; i_sb++)
+    /* Audio decoder thread's main loop */
+    while( (!p_adec->p_fifo->b_die) && (!p_adec->p_fifo->b_error) )
     {
-        if (pi_allocation_0[i_sb])
+        s16 * buffer;
+        adec_sync_info_t sync_info;
+
+        if( DECODER_FIFO_START( *p_adec->p_fifo)->i_pts )
         {
-            SWITCH (pi_scfsi_0, pf_scalefactor_0_0, pf_scalefactor_0_1, pf_scalefactor_0_2)
+            p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
+                DECODER_FIFO_START( *p_adec->p_fifo )->i_pts;
+            DECODER_FIFO_START(*p_adec->p_fifo)->i_pts = 0;
         }
-        if (pi_allocation_1[i_sb])
+        else
         {
-            SWITCH (pi_scfsi_1, pf_scalefactor_1_0, pf_scalefactor_1_1, pf_scalefactor_1_2)
+            p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
+                LAST_MDATE;
         }
-    }
-    for (; i_sb < i_sblimit; i_sb++)
-    {
-        if (pi_allocation_0[i_sb])
+
+        if( ! adec_SyncFrame (p_adec, &sync_info) )
         {
-            SWITCH (pi_scfsi_0, pf_scalefactor_0_0, pf_scalefactor_0_1, pf_scalefactor_0_2)
-            SWITCH (pi_scfsi_1, pf_scalefactor_1_0, pf_scalefactor_1_1, pf_scalefactor_1_2)
+            sync = 1;
+
+            p_adec->p_aout_fifo->l_rate = sync_info.sample_rate;
+
+            buffer = ((s16 *)p_adec->p_aout_fifo->buffer)
+                        + (p_adec->p_aout_fifo->l_end_frame * ADEC_FRAME_SIZE);
+
+            if( adec_DecodeFrame (p_adec, buffer) )
+            {
+                /* Ouch, failed decoding... We'll have to resync */
+                sync = 0;
+            }
+            else
+            {
+                vlc_mutex_lock (&p_adec->p_aout_fifo->data_lock);
+    
+                p_adec->p_aout_fifo->l_end_frame =
+                    (p_adec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
+                vlc_cond_signal (&p_adec->p_aout_fifo->data_wait);
+                vlc_mutex_unlock (&p_adec->p_aout_fifo->data_lock);
+            }
         }
     }
-    for (; i_sb < 32; i_sb++)
-    {
-        ppf_sample_0[0][i_sb] = .0;
-        ppf_sample_0[1][i_sb] = .0;
-        ppf_sample_0[2][i_sb] = .0;
-        ppf_sample_1[0][i_sb] = .0;
-        ppf_sample_1[1][i_sb] = .0;
-        ppf_sample_1[2][i_sb] = .0;
-    }
 
-#define GROUPTEST(pp_requantization,ppf_sample,pf_sf) \
-    requantization = *((pp_requantization)[i_sb]); \
-    if (requantization.pf_ungroup == NULL) \
-    { \
-        NeedBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
-        i_need += requantization.i_bits_per_codeword; \
-       (ppf_sample)[0][i_sb] = (f_scalefactor_0 = (pf_sf)[i_sb]) * (requantization.f_slope * \
-           (p_adec->bit_stream.buffer >> (32 - requantization.i_bits_per_codeword)) + requantization.f_offset); \
-        DumpBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
-        i_dump += requantization.i_bits_per_codeword; \
-\
-        NeedBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
-        i_need += requantization.i_bits_per_codeword; \
-       (ppf_sample)[1][i_sb] = f_scalefactor_0 * (requantization.f_slope * \
-           (p_adec->bit_stream.buffer >> (32 - requantization.i_bits_per_codeword)) + requantization.f_offset); \
-        DumpBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
-        i_dump += requantization.i_bits_per_codeword; \
-\
-        NeedBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
-        i_need += requantization.i_bits_per_codeword; \
-       (ppf_sample)[2][i_sb] = f_scalefactor_0 * (requantization.f_slope * \
-           (p_adec->bit_stream.buffer >> (32 - requantization.i_bits_per_codeword)) + requantization.f_offset); \
-        DumpBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
-        i_dump += requantization.i_bits_per_codeword; \
-    } \
-    else \
-    { \
-        NeedBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
-        i_need += requantization.i_bits_per_codeword; \
-        pf_ungroup = requantization.pf_ungroup + 3 * \
-           (p_adec->bit_stream.buffer >> (32 - requantization.i_bits_per_codeword)); \
-        DumpBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
-        i_dump += requantization.i_bits_per_codeword; \
-       (ppf_sample)[0][i_sb] = (f_scalefactor_0 = (pf_sf)[i_sb]) * pf_ungroup[0]; \
-       (ppf_sample)[1][i_sb] = f_scalefactor_0 * pf_ungroup[1]; \
-       (ppf_sample)[2][i_sb] = f_scalefactor_0 * pf_ungroup[2]; \
-    }
-/* #define GROUPTEST */
-
-#define READ_SAMPLE_L2S(pf_scalefactor_0,pf_scalefactor_1,i_grlimit) \
-    for (; i_gr < (i_grlimit); i_gr++) \
-    { \
-        for (i_sb = 0; i_sb < i_bound; i_sb++) \
-        { \
-            if (pi_allocation_0[i_sb]) \
-            { \
-                GROUPTEST (pp_requantization_0, ppf_sample_0, (pf_scalefactor_0)) \
-            } \
-            if (pi_allocation_1[i_sb]) \
-            { \
-                GROUPTEST (pp_requantization_1, ppf_sample_1, (pf_scalefactor_1)) \
-            } \
-        } \
-        for (; i_sb < i_sblimit; i_sb++) \
-        { \
-            if (pi_allocation_0[i_sb]) \
-            { \
-                requantization = *(pp_requantization_0[i_sb]); \
-                if (requantization.pf_ungroup == NULL) \
-                { \
-                    NeedBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
-                    i_need += requantization.i_bits_per_codeword; \
-                    ppf_sample_0[0][i_sb] = (f_scalefactor_0 = (pf_scalefactor_0)[i_sb]) * \
-                       (requantization.f_slope * (f_dummy = \
-                       (float)(p_adec->bit_stream.buffer >> (32 - requantization.i_bits_per_codeword))) + \
-                        requantization.f_offset); \
-                    DumpBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
-                    i_dump += requantization.i_bits_per_codeword; \
-                    ppf_sample_1[0][i_sb] = (f_scalefactor_1 = (pf_scalefactor_1)[i_sb]) * \
-                       (requantization.f_slope * f_dummy + requantization.f_offset); \
-\
-                    NeedBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
-                    i_need += requantization.i_bits_per_codeword; \
-                    ppf_sample_0[1][i_sb] = f_scalefactor_0 * \
-                       (requantization.f_slope * (f_dummy = \
-                       (float)(p_adec->bit_stream.buffer >> (32 - requantization.i_bits_per_codeword))) + \
-                        requantization.f_offset); \
-                    DumpBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
-                    i_dump += requantization.i_bits_per_codeword; \
-                    ppf_sample_1[1][i_sb] = f_scalefactor_1 * \
-                       (requantization.f_slope * f_dummy + requantization.f_offset); \
-\
-                    NeedBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
-                    i_need += requantization.i_bits_per_codeword; \
-                    ppf_sample_0[2][i_sb] = f_scalefactor_0 * \
-                       (requantization.f_slope * (f_dummy = \
-                       (float)(p_adec->bit_stream.buffer >> (32 - requantization.i_bits_per_codeword))) + \
-                        requantization.f_offset); \
-                    DumpBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
-                    i_dump += requantization.i_bits_per_codeword; \
-                    ppf_sample_1[2][i_sb] = f_scalefactor_1 * \
-                       (requantization.f_slope * f_dummy + requantization.f_offset); \
-                } \
-                else \
-                { \
-                    NeedBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
-                    i_need += requantization.i_bits_per_codeword; \
-                    pf_ungroup = requantization.pf_ungroup + 3 * \
-                       (p_adec->bit_stream.buffer >> (32 - requantization.i_bits_per_codeword)); \
-                    DumpBits (&p_adec->bit_stream, requantization.i_bits_per_codeword); \
-                    i_dump += requantization.i_bits_per_codeword; \
-\
-                    ppf_sample_0[0][i_sb] = (f_scalefactor_0 = (pf_scalefactor_0)[i_sb]) * pf_ungroup[0]; \
-                    ppf_sample_0[1][i_sb] = f_scalefactor_0 * pf_ungroup[1]; \
-                    ppf_sample_0[2][i_sb] = f_scalefactor_0 * pf_ungroup[2]; \
-\
-                    ppf_sample_1[0][i_sb] = (f_scalefactor_1 = (pf_scalefactor_1)[i_sb]) * pf_ungroup[0]; \
-                    ppf_sample_1[1][i_sb] = f_scalefactor_1 * pf_ungroup[1]; \
-                    ppf_sample_1[2][i_sb] = f_scalefactor_1 * pf_ungroup[2]; \
-                } \
-            } \
-        } \
-\
-        DCT32 (ppf_sample_0[0], &p_adec->bank_0); \
-        PCM (&p_adec->bank_0, &p_s16, 2); \
-        p_s16 -= 63; \
-\
-        DCT32 (ppf_sample_1[0], &p_adec->bank_1); \
-        PCM (&p_adec->bank_1, &p_s16, 2); \
-        p_s16 -= 1; \
-\
-        DCT32 (ppf_sample_0[1], &p_adec->bank_0); \
-        PCM (&p_adec->bank_0, &p_s16, 2); \
-        p_s16 -= 63; \
-\
-        DCT32 (ppf_sample_1[1], &p_adec->bank_1); \
-        PCM (&p_adec->bank_1, &p_s16, 2); \
-        p_s16 -= 1; \
-\
-        DCT32 (ppf_sample_0[2], &p_adec->bank_0); \
-        PCM (&p_adec->bank_0, &p_s16, 2); \
-        p_s16 -= 63; \
-\
-        DCT32 (ppf_sample_1[2], &p_adec->bank_1); \
-        PCM (&p_adec->bank_1, &p_s16, 2); \
-        p_s16 -= 1; \
+    /* If b_error is set, the audio decoder thread enters the error loop */
+    if( p_adec->p_fifo->b_error ) 
+    {
+        ErrorThread( p_adec );
     }
-/* #define READ_SAMPLE_L2S */
-
-    i_gr = 0;
-    p_s16 = buffer;
-
-    READ_SAMPLE_L2S (pf_scalefactor_0_0, pf_scalefactor_1_0, 4)
-    READ_SAMPLE_L2S (pf_scalefactor_0_1, pf_scalefactor_1_1, 8)
-    READ_SAMPLE_L2S (pf_scalefactor_0_2, pf_scalefactor_1_2, 12)
 
-    p_adec->bit_stream.buffer = 0;
-    p_adec->bit_stream.i_available = 0;
-    return (6);
+    /* End of the audio decoder thread */
+    EndThread( p_adec );
 }
 
-/**** wkn ****/
-
-int adec_init (audiodec_t * p_adec)
+/*****************************************************************************
+ * ErrorThread : audio decoder's RunThread() error loop
+ *****************************************************************************
+ * This function is called when an error occured during thread main's loop. The
+ * thread can still receive feed, but must be ready to terminate as soon as
+ * possible.
+ *****************************************************************************/
+static void ErrorThread ( adec_thread_t *p_adec )
 {
-    p_adec->bank_0.actual = p_adec->bank_0.v1;
-    p_adec->bank_0.pos = 0;
-    p_adec->bank_1.actual = p_adec->bank_1.v1;
-    p_adec->bank_1.pos = 0;
-    return 0;
-}
+    /* We take the lock, because we are going to read/write the start/end
+     * indexes of the decoder fifo */
+    vlc_mutex_lock ( &p_adec->p_fifo->data_lock );
 
-int adec_sync_frame (audiodec_t * p_adec, adec_sync_info_t * p_sync_info)
-{
-    static int mpeg1_sample_rate[3] = {44100, 48000, 32000};
-    static int mpeg1_layer1_bit_rate[15] = {
-       0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448
-    };
-    static int mpeg1_layer2_bit_rate[15] = {
-       0, 32, 48, 56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, 384
-    };
-    static int mpeg2_layer1_bit_rate[15] = {
-       0, 32, 48, 56,  64,  80,  96, 112, 128, 144, 160, 176, 192, 224, 256
-    };
-    static int mpeg2_layer2_bit_rate[15] = {
-       0,  8, 16, 24,  32,  40,  48,  56,  64,  80,  96, 112, 128, 144, 160
-    };
-    u32 header;
-    int index;
-    int * bit_rate_table;
-    int sample_rate;
-    int bit_rate;
-    int frame_size;
-
-    p_adec->bit_stream.total_bytes_read = 0;
-    header = GetByte (&p_adec->bit_stream) << 24;
-    header |= GetByte (&p_adec->bit_stream) << 16;
-    header |= GetByte (&p_adec->bit_stream) << 8;
-    header |= GetByte (&p_adec->bit_stream);
-
-    p_adec->header = header;
-
-    /* basic header check : sync word, no emphasis */
-    if ((header & 0xfff00003) != 0xfff00000)
-       return 1;
-
-    index = (header >> 10) & 3;                /* sample rate index */
-    if (index > 2)
-       return 1;
-    sample_rate = mpeg1_sample_rate[index];
-
-    switch ((header >> 17) & 7) {
-    case 2:    /* mpeg 2, layer 2 */
-       sample_rate >>= 1;              /* half sample rate for mpeg2 */
-       bit_rate_table = mpeg2_layer2_bit_rate;
-       break;
-    case 3:    /* mpeg 2, layer 1 */
-       sample_rate >>= 1;              /* half sample rate for mpeg2 */
-       bit_rate_table = mpeg2_layer1_bit_rate;
-       break;
-    case 6:    /* mpeg1, layer 2 */
-       bit_rate_table = mpeg1_layer2_bit_rate;
-       break;
-    case 7:    /* mpeg1, layer 1 */
-       bit_rate_table = mpeg1_layer1_bit_rate;
-       break;
-    default:   /* invalid layer */
-       return 1;
-    }
+    /* Wait until a `die' order is sent */
+    while ( !p_adec->p_fifo->b_die ) 
+    {
+        /* Trash all received PES packets */
+        while ( !DECODER_FIFO_ISEMPTY(*p_adec->p_fifo) ) 
+        {
+            p_adec->p_fifo->pf_delete_pes ( p_adec->p_fifo->p_packets_mgt,
+                                   DECODER_FIFO_START(*p_adec->p_fifo) );
+            DECODER_FIFO_INCSTART ( *p_adec->p_fifo );
+        }
 
-    index = (header >> 12) & 15;       /* bit rate index */
-    if (index > 14)
-       return 1;
-    bit_rate = bit_rate_table[index];
-
-    p_sync_info->sample_rate = sample_rate;
-    p_sync_info->bit_rate = bit_rate;
-
-    if ((header & 0x60000) == 0x60000) {       /* layer 1 */
-       frame_size = 48000 * bit_rate / sample_rate;
-       if (header & 0x200)     /* padding */
-           frame_size += 4;
-    } else {   /* layer >1 */
-       frame_size = 144000 * bit_rate / sample_rate;
-       if (header & 0x200)     /* padding */
-           frame_size ++;
+        /* Waiting for the input thread to put new PES packets in the fifo */
+        vlc_cond_wait ( &p_adec->p_fifo->data_wait, &p_adec->p_fifo->data_lock );
     }
 
-    p_sync_info->frame_size = frame_size;
-    p_adec->frame_size = frame_size;
-
-    return 0;
+    /* We can release the lock before leaving */
+    vlc_mutex_unlock ( &p_adec->p_fifo->data_lock );
 }
 
-int adec_decode_frame (audiodec_t * p_adec, s16 * buffer)
+/*****************************************************************************
+ * EndThread : audio decoder thread destruction
+ *****************************************************************************
+ * This function is called when the thread ends after a sucessful
+ * initialization.
+ *****************************************************************************/
+static void EndThread ( adec_thread_t *p_adec )
 {
-    p_adec->bit_stream.i_available = 0;
+    intf_DbgMsg ( "adec debug: destroying audio decoder thread %p", p_adec );
 
-    adec_Layer2_Stereo (p_adec, buffer);
-
-    if (p_adec->bit_stream.total_bytes_read > p_adec->frame_size)
-       return 1;
+    /* If the audio output fifo was created, we destroy it */
+    if ( p_adec->p_aout_fifo != NULL ) 
+    {
+        aout_DestroyFifo ( p_adec->p_aout_fifo );
 
-    while (p_adec->bit_stream.total_bytes_read < p_adec->frame_size)
-       GetByte (&p_adec->bit_stream);
+        /* Make sure the output thread leaves the NextFrame() function */
+        vlc_mutex_lock (&(p_adec->p_aout_fifo->data_lock));
+        vlc_cond_signal (&(p_adec->p_aout_fifo->data_wait));
+        vlc_mutex_unlock (&(p_adec->p_aout_fifo->data_lock));
+    }
+    /* Destroy descriptor */
+    free( p_adec->p_config );
+    free( p_adec );
 
-    return 0;
+    intf_DbgMsg ("adec debug: audio decoder thread %p destroyed", p_adec);
 }
+