Ajout des fichiers pour la gestion du lpcm.
authorDamien Lucas <nitrox@videolan.org>
Wed, 24 May 2000 21:48:18 +0000 (21:48 +0000)
committerDamien Lucas <nitrox@videolan.org>
Wed, 24 May 2000 21:48:18 +0000 (21:48 +0000)
Il reste � impl�menter le lpcm au niveau de l'input et �crire le d�codage.

Makefile.in
include/input.h
include/lpcm_decoder.h [new file with mode: 0644]
include/lpcm_decoder_thread.h [new file with mode: 0644]
src/input/input.c
src/input/input_ctrl.c
src/input/input_psi.c
src/lpcm_decoder/lpcm_decoder.c [new file with mode: 0644]
src/lpcm_decoder/lpcm_decoder_thread.c [new file with mode: 0644]

index 2f9fa13..053679d 100644 (file)
@@ -240,6 +240,9 @@ ac3_decoder_obj =           ac3_decoder/ac3_decoder_thread.o \
                                                ac3_decoder/ac3_rematrix.o \
                                                ac3_decoder/ac3_imdct.o \
                                                ac3_decoder/ac3_downmix.o
+                                               
+lpcm_decoder_obj =             lpcm_decoder/lpcm_decoder_thread.o \
+                                               lpcm_decoder/lpcm_decoder.o
 
 audio_decoder_obj =            audio_decoder/audio_decoder_thread.o \
                                                audio_decoder/audio_decoder.o \
@@ -288,6 +291,7 @@ C_OBJ = $(interface_obj) \
                $(audio_output_obj) \
                $(video_output_obj) \
                $(ac3_decoder_obj) \
+               $(lpcm_decoder_obj) \
                $(audio_decoder_obj) \
                $(spu_decoder_obj) \
                $(generic_decoder_obj) \
index 07c231a..de2da9e 100644 (file)
@@ -170,7 +170,7 @@ typedef struct es_descriptor_t
 #define MPEG2_AUDIO_ES          0x04
 #define AC3_AUDIO_ES            0x81
 #define DVD_SPU_ES             0x82           /* 0x82 might violate the norm */
-
+#define LPCM_AUDIO_ES           0x83
 /*****************************************************************************
  * program_descriptor_t
  *****************************************************************************
diff --git a/include/lpcm_decoder.h b/include/lpcm_decoder.h
new file mode 100644 (file)
index 0000000..7a4bdac
--- /dev/null
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ * lpcm_decoder.h : lpcm decoder interface
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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.
+ *
+ * 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.
+ *****************************************************************************/
+
+typedef struct lpcmdec_s lpcmdec_t;
+
+typedef struct lpcm_sync_info_s {
+    int sample_rate;   /* sample rate in Hz */
+    int frame_size;    /* frame size in bytes */
+    int bit_rate;      /* nominal bit rate in kbps */
+} lpcm_sync_info_t;
+
+typedef struct lpcm_byte_stream_s {
+    u8 * p_byte;
+    u8 * p_end;
+    void * info;
+} lpcm_byte_stream_t;
+
+
+int lpcm_init (lpcmdec_t * p_lpcmdec);
+int lpcm_sync_frame (lpcmdec_t * p_lpcmdec, lpcm_sync_info_t * p_sync_info);
+int lpcm_decode_frame (lpcmdec_t * p_lcpmdec, s16 * buffer);
+//static lpcm_byte_stream_t * lpcm_byte_stream (lcpmdec_t * p_lpcmdec);
+
+
+void lpcm_byte_stream_next (lpcm_byte_stream_t * p_byte_stream);
+
+typedef struct lpcm_bit_stream_s {
+    u32 buffer;
+    int i_available;
+    lpcm_byte_stream_t byte_stream;
+
+} lpcm_bit_stream_t;
+
+struct lpcmdec_s {
+    /*
+     * Input properties
+     */
+
+    /* The bit stream structure handles the PES stream at the bit level */
+    lpcm_bit_stream_t  bit_stream;
+};
+
+
+static lpcm_byte_stream_t * lpcm_byte_stream (lpcmdec_t * p_lpcmdec)
+{
+    return &(p_lpcmdec->bit_stream.byte_stream);
+}
diff --git a/include/lpcm_decoder_thread.h b/include/lpcm_decoder_thread.h
new file mode 100644 (file)
index 0000000..afeaf02
--- /dev/null
@@ -0,0 +1,62 @@
+/*****************************************************************************
+ * lpcm_decoder_thread.h : lpcm decoder thread interface
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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.
+ *
+ * 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.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * lpcmdec_thread_t : lpcm decoder thread descriptor
+ *****************************************************************************/
+typedef struct lpcmdec_thread_s
+{
+    /*
+     * Thread properties
+     */
+    vlc_thread_t        thread_id;                /* id for thread functions */
+    boolean_t           b_die;                                 /* `die' flag */
+    boolean_t           b_error;                             /* `error' flag */
+
+    /*
+     * Input properties
+     */
+    decoder_fifo_t      fifo;                  /* stores the PES stream data */
+    input_thread_t *    p_input;
+    ts_packet_t *       p_ts;
+    int                        sync_ptr;       /* sync ptr from lpcm magic header */
+
+    /*
+     * Decoder properties
+     */
+
+    lpcmdec_t            lpcm_decoder;
+
+    /*
+     * Output properties
+     */
+    aout_fifo_t *       p_aout_fifo; /* stores the decompressed audio frames */
+    aout_thread_t *     p_aout;           /* needed to create the audio fifo */
+
+} lpcmdec_thread_t;
+
+/*****************************************************************************
+ * Prototypes
+ *****************************************************************************/
+lpcmdec_thread_t *      lpcmdec_CreateThread( input_thread_t * p_input );
+void                    lpcmdec_DestroyThread( lpcmdec_thread_t * p_lcpmdec );
index 4f82827..fe480e2 100644 (file)
@@ -60,6 +60,9 @@
 #include "ac3_decoder.h"              /* ac3dec_t (for ac3_decoder_thread.h) */
 #include "ac3_decoder_thread.h"                           /* ac3dec_thread_t */
 
+#include "lpcm_decoder.h"
+#include "lpcm_decoder_thread.h"
+
 #include "video.h"                          /* picture_t (for video_output.h) */
 #include "video_output.h"                                   /* vout_thread_t */
 
@@ -444,6 +447,9 @@ static void EndThread( input_thread_t * p_input )
         case AC3_AUDIO_ES:
             ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_es_loop]->p_dec) );
             break;
+        case LPCM_AUDIO_ES:
+            lpcmdec_DestroyThread((lpcmdec_thread_t *)(p_input->pp_selected_es[i_es_loop]->p_dec) );
+            break;
         case DVD_SPU_ES:
             spudec_DestroyThread( (spudec_thread_t *)(p_input->pp_selected_es[i_es_loop]->p_dec) );
             break;
@@ -1225,6 +1231,10 @@ static __inline__ void input_ParsePES( input_thread_t *p_input,
                 p_fifo = &(((ac3dec_thread_t *)(p_es_descriptor->p_dec))->fifo);
                 break;
 
+           case LPCM_AUDIO_ES:
+                p_fifo = &(((lpcmdec_thread_t *)(p_es_descriptor->p_dec))->fifo);
+                break;
+
             case DVD_SPU_ES:
                 /* we skip the first byte at the beginning of the
                  * subpicture payload, it only contains the SPU ID. */
index 9f37732..0fac448 100644 (file)
@@ -30,7 +30,7 @@
 
 #include <sys/types.h>                        /* on BSD, uio.h needs types.h */
 #include <sys/uio.h>                                            /* "input.h" */
-
+#include <stdio.h>
 #include <netinet/in.h>                                             /* ntohs */
 
 #include "config.h"
@@ -53,6 +53,9 @@
 #include "ac3_decoder.h"              /* ac3dec_t (for ac3_decoder_thread.h) */
 #include "ac3_decoder_thread.h"                           /* ac3dec_thread_t */
 
+#include "lpcm_decoder.h"
+#include "lpcm_decoder_thread.h"
+
 #include "video.h"                          /* picture_t (for video_output.h) */
 #include "video_output.h"                                   /* vout_thread_t */
 
@@ -122,7 +125,9 @@ int input_AddPgrmElem( input_thread_t *p_input, int i_current_id )
                 /* Spawn the decoder. */
                 switch( p_input->p_es[i_es_loop].i_type )
                 {
+                    
                     case AC3_AUDIO_ES:
+                        fprintf (stderr, "Start an AC3 decoder\n");
                         /* Spawn ac3 thread */
                         if ( ((ac3dec_thread_t *)(p_input->p_es[i_es_loop].p_dec) =
                             ac3dec_CreateThread(p_input)) == NULL )
@@ -133,6 +138,19 @@ int input_AddPgrmElem( input_thread_t *p_input, int i_current_id )
                         }
                         break;
 
+                            case LPCM_AUDIO_ES:
+                        /* Spawn lpcm thread */
+                        fprintf (stderr, "Start a LPCM decoder\n");
+                        if ( ((lpcmdec_thread_t *)(p_input->p_es[i_es_loop].p_dec) =
+                            lpcmdec_CreateThread(p_input)) == NULL )
+                        {
+                            intf_ErrMsg( "LPCM Debug: Could not start lpcm decoder\n" );
+                            vlc_mutex_unlock( &p_input->es_lock );
+                            return( -1 );
+                        }
+                        break;
+
+
                     case DVD_SPU_ES:
                         /* Spawn spu thread */
                         if ( ((spudec_thread_t *)(p_input->p_es[i_es_loop].p_dec) =
@@ -248,6 +266,10 @@ int input_DelPgrmElem( input_thread_t *p_input, int i_current_id )
                     case AC3_AUDIO_ES:
                         ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
                         break;
+                       
+                    case LPCM_AUDIO_ES:
+                        lpcmdec_DestroyThread( (lpcmdec_thread_t *)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
+                        break;
 
                     case DVD_SPU_ES:
                         spudec_DestroyThread( (spudec_thread_t *)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
index 29b061e..5fa0d56 100644 (file)
@@ -654,7 +654,16 @@ static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input )
                               }
                           break;
 
-                      case DVD_SPU_ES:
+                      case LPCM_AUDIO_ES:
+                          if ( p_main->b_audio )
+                          {
+                              /* Spawn an lpcm thread */
+                              input_AddPgrmElem( p_input,
+                                  p_input->p_es[i_es_loop].i_id );
+                              }
+                          break;
+
+                     case DVD_SPU_ES:
                           if ( p_main->b_video )
                           {
                               /* Spawn a spu decoder thread */
diff --git a/src/lpcm_decoder/lpcm_decoder.c b/src/lpcm_decoder/lpcm_decoder.c
new file mode 100644 (file)
index 0000000..68d9fcf
--- /dev/null
@@ -0,0 +1,64 @@
+/*****************************************************************************
+ * lpcm_decoder.c: core lpcm decoder
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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.
+ *
+ * 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.
+ *****************************************************************************/
+#include <stdio.h>
+#include "defs.h"
+
+#include "int_types.h"
+#include "lpcm_decoder.h"
+
+int lpcm_init (lpcmdec_t * p_lpcmdec)
+{
+    fprintf (stderr, "LPCM Debug: lpmcm init called\n");
+    return 0;
+}
+
+int lpcm_decode_frame (lpcmdec_t * p_lpcmdec, s16 * buffer)
+{
+/*
+ * XXX was part of ac3dec, is to change
+    
+    int i;
+
+    if (parse_bsi (p_ac3dec))
+        return 1;
+
+    for (i = 0; i < 6; i++) {
+        if (parse_audblk (p_ac3dec, i))
+            return 1;
+        if (exponent_unpack (p_ac3dec))
+            return 1;
+        bit_allocate (p_ac3dec);
+        mantissa_unpack (p_ac3dec);
+        if  (p_ac3dec->bsi.acmod == 0x2)
+            rematrix (p_ac3dec);
+        imdct (p_ac3dec);
+        downmix (p_ac3dec, buffer);
+
+        buffer += 2*256;
+    }
+
+    parse_auxdata (p_ac3dec);
+*/
+    
+    return 0;
+}
diff --git a/src/lpcm_decoder/lpcm_decoder_thread.c b/src/lpcm_decoder/lpcm_decoder_thread.c
new file mode 100644 (file)
index 0000000..85c9d28
--- /dev/null
@@ -0,0 +1,309 @@
+/*****************************************************************************
+ * lpcm_decoder_thread.c: lpcm decoder thread
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * 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.
+ *
+ * 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.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <unistd.h>                                              /* getpid() */
+
+#include <stdio.h>                                           /* "intf_msg.h" */
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <sys/types.h>                        /* on BSD, uio.h needs types.h */
+#include <sys/uio.h>                                            /* "input.h" */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+#include "debug.h"                                      /* "input_netlist.h" */
+
+#include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
+
+#include "input.h"                                           /* pes_packet_t */
+#include "input_netlist.h"                         /* input_NetlistFreePES() */
+#include "decoder_fifo.h"         /* DECODER_FIFO_(ISEMPTY|START|INCSTART)() */
+
+#include "audio_output.h"
+
+#include "lpcm_decoder.h"
+#include "lpcm_decoder_thread.h"
+
+#define LPCMDEC_FRAME_SIZE (2*1536)                    /* May not be usefull */
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int      InitThread              (lpcmdec_thread_t * p_adec);
+static void     RunThread               (lpcmdec_thread_t * p_adec);
+static void     ErrorThread             (lpcmdec_thread_t * p_adec);
+static void     EndThread               (lpcmdec_thread_t * p_adec);
+
+/*****************************************************************************
+ * lpcmdec_CreateThread: creates an lpcm decoder thread
+ *****************************************************************************/
+lpcmdec_thread_t * lpcmdec_CreateThread (input_thread_t * p_input)
+{
+    lpcmdec_thread_t *   p_lpcmdec;
+    fprintf (stderr, "LPCM Debug: creating lpcm decoder thread\n");
+
+    /* Allocate the memory needed to store the thread's structure */
+    if ((p_lpcmdec = (lpcmdec_thread_t *)malloc (sizeof(lpcmdec_thread_t))) == NULL) {
+        fprintf (stderr, "LPCM Error: not enough memory for lpcmdec_CreateThread() to create the new thread\n");
+        return NULL;
+    }
+
+    /*
+     * Initialize the thread properties
+     */
+    p_lpcmdec->b_die = 0;
+    p_lpcmdec->b_error = 0;
+
+    /*
+     * Initialize the input properties
+     */
+    /* Initialize the decoder fifo's data lock and conditional variable and set
+     * its buffer as empty */
+    vlc_mutex_init (&p_lpcmdec->fifo.data_lock);
+    vlc_cond_init (&p_lpcmdec->fifo.data_wait);
+    p_lpcmdec->fifo.i_start = 0;
+    p_lpcmdec->fifo.i_end = 0;
+
+    /* Initialize the lpcm decoder structures */
+    lpcm_init (&p_lpcmdec->lpcm_decoder);
+
+    /* Initialize the bit stream structure */
+    p_lpcmdec->p_input = p_input;
+
+    /*
+     * Initialize the output properties
+     */
+    p_lpcmdec->p_aout = p_input->p_aout;
+    p_lpcmdec->p_aout_fifo = NULL;
+
+    /* Spawn the lpcm decoder thread */
+    if (vlc_thread_create(&p_lpcmdec->thread_id, "lpcm decoder", (vlc_thread_func_t)RunThread, (void *)p_lpcmdec)) {
+        fprintf  (stderr, "LPCM Error: can't spawn lpcm decoder thread\n");
+        free (p_lpcmdec);
+        return NULL;
+    }
+
+    fprintf (stderr, "LPCM Debug: lpcm decoder thread (%p) created\n", p_lpcmdec);
+    return p_lpcmdec;
+}
+
+/*****************************************************************************
+ * lpcmdec_DestroyThread: destroys an lpcm decoder thread
+ *****************************************************************************/
+void lpcmdec_DestroyThread (lpcmdec_thread_t * p_lpcmdec)
+{
+    fprintf (stderr, "LPCM Debug: requesting termination of lpcm decoder thread %p\n", p_lpcmdec);
+
+    /* Ask thread to kill itself */
+    p_lpcmdec->b_die = 1;
+
+    /* Make sure the decoder thread leaves the GetByte() function */
+    vlc_mutex_lock (&(p_lpcmdec->fifo.data_lock));
+    vlc_cond_signal (&(p_lpcmdec->fifo.data_wait));
+    vlc_mutex_unlock (&(p_lpcmdec->fifo.data_lock));
+
+    /* Waiting for the decoder thread to exit */
+    /* Remove this as soon as the "status" flag is implemented */
+    vlc_thread_join (p_lpcmdec->thread_id);
+}
+
+/* Following functions are local */
+
+/*****************************************************************************
+ * InitThread : initialize an lpcm decoder thread
+ *****************************************************************************/
+static int InitThread (lpcmdec_thread_t * p_lpcmdec)
+{
+    aout_fifo_t         aout_fifo;
+    lpcm_byte_stream_t * byte_stream;
+
+    fprintf (stderr, "LPCM Debug: initializing lpcm decoder thread %p\n", p_lpcmdec);
+
+    /* Our first job is to initialize the bit stream structure with the
+     * beginning of the input stream */
+    vlc_mutex_lock (&p_lpcmdec->fifo.data_lock);
+    while (DECODER_FIFO_ISEMPTY(p_lpcmdec->fifo)) {
+        if (p_lpcmdec->b_die) {
+            vlc_mutex_unlock (&p_lpcmdec->fifo.data_lock);
+            return -1;
+        }
+        vlc_cond_wait (&p_lpcmdec->fifo.data_wait, &p_lpcmdec->fifo.data_lock);
+    }
+    p_lpcmdec->p_ts = DECODER_FIFO_START (p_lpcmdec->fifo)->p_first_ts;
+    byte_stream = lpcm_byte_stream (&p_lpcmdec->lpcm_decoder);
+    byte_stream->p_byte =
+       p_lpcmdec->p_ts->buffer + p_lpcmdec->p_ts->i_payload_start;
+    byte_stream->p_end =
+       p_lpcmdec->p_ts->buffer + p_lpcmdec->p_ts->i_payload_end;
+    byte_stream->info = p_lpcmdec;
+    vlc_mutex_unlock (&p_lpcmdec->fifo.data_lock);
+
+    aout_fifo.i_type = AOUT_ADEC_STEREO_FIFO;
+    aout_fifo.i_channels = 2;
+    aout_fifo.b_stereo = 1;
+
+    aout_fifo.l_frame_size = LPCMDEC_FRAME_SIZE;
+
+    /* Creating the audio output fifo */
+    if ((p_lpcmdec->p_aout_fifo = aout_CreateFifo(p_lpcmdec->p_aout, &aout_fifo)) == NULL) {
+        return -1;
+    }
+
+    fprintf (stderr,"LPCM Debug: lpcm decoder thread %p initialized\n", p_lpcmdec);
+    return 0;
+}
+
+/*****************************************************************************
+ * RunThread : lpcm decoder thread
+ *****************************************************************************/
+static void RunThread (lpcmdec_thread_t * p_lpcmdec)
+{
+    int sync;
+
+    fprintf (stderr,"LPCM Debug: running lpcm decoder thread (%p) (pid== %i)\n", p_lpcmdec, getpid());
+
+    msleep (INPUT_PTS_DELAY);
+
+    /* Initializing the lpcm decoder thread */
+    if (InitThread (p_lpcmdec)) 
+    {
+        p_lpcmdec->b_error = 1;
+    }
+
+    sync = 0;
+    p_lpcmdec->sync_ptr = 0;
+
+    /* lpcm decoder thread's main loop */
+    /* FIXME : do we have enough room to store the decoded frames ?? */
+   
+    while ((!p_lpcmdec->b_die) && (!p_lpcmdec->b_error))
+    {
+           s16 * buffer;
+           lpcm_sync_info_t sync_info;
+
+           if (!sync)
+        {
+            /* have to find a synchro point */
+        }
+    
+        if (DECODER_FIFO_START(p_lpcmdec->fifo)->b_has_pts)
+        {
+               p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] = DECODER_FIFO_START(p_lpcmdec->fifo)->i_pts;
+               DECODER_FIFO_START(p_lpcmdec->fifo)->b_has_pts = 0;
+        }
+        else
+        {
+               p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] = LAST_MDATE;
+        }
+
+       p_lpcmdec->p_aout_fifo->l_rate = sync_info.sample_rate;
+
+           buffer = ((s16 *)p_lpcmdec->p_aout_fifo->buffer) + (p_lpcmdec->p_aout_fifo->l_end_frame * LPCMDEC_FRAME_SIZE);
+
+           if (lpcm_decode_frame (&p_lpcmdec->lpcm_decoder, buffer))
+        {
+               sync = 0;
+               goto bad_frame;
+           }
+
+           vlc_mutex_lock (&p_lpcmdec->p_aout_fifo->data_lock);
+           p_lpcmdec->p_aout_fifo->l_end_frame = (p_lpcmdec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
+           vlc_cond_signal (&p_lpcmdec->p_aout_fifo->data_wait);
+           vlc_mutex_unlock (&p_lpcmdec->p_aout_fifo->data_lock);
+
+        fprintf(stderr, "LPCM Debug: %x\n", *buffer);
+        bad_frame:
+    }
+
+    /* If b_error is set, the lpcm decoder thread enters the error loop */
+    if (p_lpcmdec->b_error)
+    {
+        ErrorThread (p_lpcmdec);
+    }
+
+    /* End of the lpcm decoder thread */
+    EndThread (p_lpcmdec);
+}
+
+/*****************************************************************************
+ * ErrorThread : lpcm decoder's RunThread() error loop
+ *****************************************************************************/
+static void ErrorThread (lpcmdec_thread_t * p_lpcmdec)
+{
+    /* We take the lock, because we are going to read/write the start/end
+     * indexes of the decoder fifo */
+    vlc_mutex_lock (&p_lpcmdec->fifo.data_lock);
+
+    /* Wait until a `die' order is sent */
+    while (!p_lpcmdec->b_die) {
+        /* Trash all received PES packets */
+        while (!DECODER_FIFO_ISEMPTY(p_lpcmdec->fifo)) {
+            input_NetlistFreePES (p_lpcmdec->p_input, DECODER_FIFO_START(p_lpcmdec->fifo));
+            DECODER_FIFO_INCSTART (p_lpcmdec->fifo);
+        }
+
+        /* Waiting for the input thread to put new PES packets in the fifo */
+        vlc_cond_wait (&p_lpcmdec->fifo.data_wait, &p_lpcmdec->fifo.data_lock);
+    }
+
+    /* We can release the lock before leaving */
+    vlc_mutex_unlock (&p_lpcmdec->fifo.data_lock);
+}
+
+/*****************************************************************************
+ * EndThread : lpcm decoder thread destruction
+ *****************************************************************************/
+static void EndThread (lpcmdec_thread_t * p_lpcmdec)
+{
+    fprintf (stderr, "LPCM Debug: destroying lpcm decoder thread %p\n", p_lpcmdec);
+
+    /* If the audio output fifo was created, we destroy it */
+    if (p_lpcmdec->p_aout_fifo != NULL) {
+        aout_DestroyFifo (p_lpcmdec->p_aout_fifo);
+
+        /* Make sure the output thread leaves the NextFrame() function */
+        vlc_mutex_lock (&(p_lpcmdec->p_aout_fifo->data_lock));
+        vlc_cond_signal (&(p_lpcmdec->p_aout_fifo->data_wait));
+        vlc_mutex_unlock (&(p_lpcmdec->p_aout_fifo->data_lock));
+    }
+
+    /* Destroy descriptor */
+    free (p_lpcmdec);
+
+    fprintf (stderr, "LPCM Debug: lpcm decoder thread %p destroyed\n", p_lpcmdec);
+}
+
+void lpcm_byte_stream_next (lpcm_byte_stream_t * p_byte_stream)
+{
+//    lpcmdec_thread_t * p_lpcmdec = p_byte_stream->info;
+
+    /* We are looking for the next TS packet that contains real data,
+     * and not just a PES header */
+}