From a3c92b8fe71f3b308de5b1205ffc2ef7760764ff Mon Sep 17 00:00:00 2001 From: Henri Fallon Date: Tue, 12 Jun 2001 13:50:09 +0000 Subject: [PATCH] Added LPCM support. It should work with stereo LPCM. Untested with 5-ways LPCM streams. --- Makefile | 1 - TODO | 4 +- src/lpcm_decoder/lpcm_decoder.c | 73 ----------- src/lpcm_decoder/lpcm_decoder.h | 68 ---------- src/lpcm_decoder/lpcm_decoder_thread.c | 174 +++++++++++++------------ src/lpcm_decoder/lpcm_decoder_thread.h | 13 +- 6 files changed, 96 insertions(+), 237 deletions(-) delete mode 100644 src/lpcm_decoder/lpcm_decoder.c delete mode 100644 src/lpcm_decoder/lpcm_decoder.h diff --git a/Makefile b/Makefile index 0efeb27481..10aa579ca4 100644 --- a/Makefile +++ b/Makefile @@ -77,7 +77,6 @@ AC3_SPDIF := src/ac3_spdif/ac3_spdif.o \ src/ac3_spdif/ac3_iec958.o LPCM_DECODER := src/lpcm_decoder/lpcm_decoder_thread.o \ - src/lpcm_decoder/lpcm_decoder.o AUDIO_DECODER := src/audio_decoder/audio_decoder.o \ src/audio_decoder/adec_generic.o \ diff --git a/TODO b/TODO index ef0874c730..7e360b8438 100644 --- a/TODO +++ b/TODO @@ -56,7 +56,7 @@ Description: Cope with vls/vlc clock jitter The internal clocks of the server and the client are not assured to be in perfect synchronization, which may be annoying when playing a movie. Reduce this jitter by using a well-chosen filter. -Status: Todo +Status: Done 1 May 2001 (henri) Task: 0x58 Difficulty: Medium @@ -541,7 +541,7 @@ Urgency: Normal Description: LPCM decoder The LPCM decoder is full of stubs, it only parses the stream but does not decode it. Fix this. -Status: Todo +Status: Done 12 Jun 2001 (henri) Task: 0x1c Difficulty: Guru diff --git a/src/lpcm_decoder/lpcm_decoder.c b/src/lpcm_decoder/lpcm_decoder.c deleted file mode 100644 index b9b98ea749..0000000000 --- a/src/lpcm_decoder/lpcm_decoder.c +++ /dev/null @@ -1,73 +0,0 @@ -/***************************************************************************** - * lpcm_decoder.c: core lpcm decoder - ***************************************************************************** - * Copyright (C) 1999, 2000 VideoLAN - * $Id: lpcm_decoder.c,v 1.7 2001/04/06 09:15:48 sam Exp $ - * - * Authors: Samuel Hocevar - * - * 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, USA. - *****************************************************************************/ -#include "defs.h" - -#include -#include /* memcpy(), memset() */ - -#include "config.h" -#include "common.h" -#include "threads.h" -#include "mtime.h" - -#include "intf_msg.h" - -//#include "int_types.h" -#include "lpcm_decoder.h" - -int lpcm_init (lpcmdec_t * p_lpcmdec) -{ - intf_DbgMsg( "LPCM Debug: lpmcm init called" ); - 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.h b/src/lpcm_decoder/lpcm_decoder.h deleted file mode 100644 index 8fbfc0b6bd..0000000000 --- a/src/lpcm_decoder/lpcm_decoder.h +++ /dev/null @@ -1,68 +0,0 @@ -/***************************************************************************** - * lpcm_decoder.h : lpcm decoder interface - ***************************************************************************** - * Copyright (C) 1999, 2000 VideoLAN - * $Id: lpcm_decoder.h,v 1.3 2001/03/21 13:42:34 sam Exp $ - * - * Authors: Samuel Hocevar - * - * 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/src/lpcm_decoder/lpcm_decoder_thread.c b/src/lpcm_decoder/lpcm_decoder_thread.c index cecef936ed..6678958c68 100644 --- a/src/lpcm_decoder/lpcm_decoder_thread.c +++ b/src/lpcm_decoder/lpcm_decoder_thread.c @@ -2,9 +2,10 @@ * lpcm_decoder_thread.c: lpcm decoder thread ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: lpcm_decoder_thread.c,v 1.15 2001/05/31 01:37:08 sam Exp $ + * $Id: lpcm_decoder_thread.c,v 1.16 2001/06/12 13:50:09 henri Exp $ * * Authors: Samuel Hocevar + * Henri Fallon * * 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 @@ -46,11 +47,8 @@ #include "audio_output.h" -#include "lpcm_decoder.h" #include "lpcm_decoder_thread.h" -#define LPCMDEC_FRAME_SIZE (2*1536) /* May be useless */ - /***************************************************************************** * Local prototypes *****************************************************************************/ @@ -62,14 +60,16 @@ static void EndThread (lpcmdec_thread_t * p_adec); /***************************************************************************** * lpcmdec_CreateThread: creates an lpcm decoder thread *****************************************************************************/ -vlc_thread_t lpcmdec_CreateThread (adec_config_t * p_config) +vlc_thread_t lpcmdec_CreateThread( adec_config_t * p_config ) { lpcmdec_thread_t * p_lpcmdec; - intf_DbgMsg ( "lpcm: creating lpcm decoder thread" ); + intf_DbgMsg( "LPCM: creating lpcm decoder thread" ); /* Allocate the memory needed to store the thread's structure */ - if ((p_lpcmdec = (lpcmdec_thread_t *)malloc (sizeof(lpcmdec_thread_t))) == NULL) { - intf_ErrMsg ( "lpcm error: cannot create lpcmdec_thread_t" ); + if( (p_lpcmdec = (lpcmdec_thread_t *)malloc (sizeof(lpcmdec_thread_t)) ) + == NULL) + { + intf_ErrMsg( "LPCM : error : cannot create lpcmdec_thread_t" ); return 0; } @@ -79,23 +79,21 @@ vlc_thread_t lpcmdec_CreateThread (adec_config_t * p_config) p_lpcmdec->p_config = p_config; p_lpcmdec->p_fifo = p_config->decoder_config.p_decoder_fifo; - - /* Initialize the lpcm decoder structures */ - lpcm_init (&p_lpcmdec->lpcm_decoder); - /* * Initialize the output properties */ 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)) { - intf_ErrMsg ( "lpcm error: cannot spawn thread" ); + if( vlc_thread_create( &p_lpcmdec->thread_id, "lpcm decoder", + (vlc_thread_func_t)RunThread, (void *)p_lpcmdec ) ) + { + intf_ErrMsg( "LPCM : error : cannot spawn thread" ); free (p_lpcmdec); return 0; } - intf_DbgMsg ( "LPCM Debug: lpcm decoder thread (%p) created", p_lpcmdec ); + intf_DbgMsg( "LPCM Debug: lpcm decoder thread (%p) created\n", p_lpcmdec ); return p_lpcmdec->thread_id; } @@ -106,37 +104,44 @@ vlc_thread_t lpcmdec_CreateThread (adec_config_t * p_config) *****************************************************************************/ static int InitThread (lpcmdec_thread_t * p_lpcmdec) { - lpcm_byte_stream_t * byte_stream; - intf_DbgMsg ( "LPCM Debug: initializing lpcm decoder thread %p", p_lpcmdec ); + intf_DbgMsg ( "lpcm Debug: initializing lpcm decoder thread %p", + p_lpcmdec ); /* Our first job is to initialize the bit stream structure with the * beginning of the input stream */ vlc_mutex_lock (&p_lpcmdec->p_fifo->data_lock); - while (DECODER_FIFO_ISEMPTY(*p_lpcmdec->p_fifo)) { - if (p_lpcmdec->p_fifo->b_die) { + + while (DECODER_FIFO_ISEMPTY(*p_lpcmdec->p_fifo)) + { + if (p_lpcmdec->p_fifo->b_die) + { vlc_mutex_unlock (&p_lpcmdec->p_fifo->data_lock); return -1; } - vlc_cond_wait (&p_lpcmdec->p_fifo->data_wait, &p_lpcmdec->p_fifo->data_lock); + vlc_cond_wait (&p_lpcmdec->p_fifo->data_wait, + &p_lpcmdec->p_fifo->data_lock); } + p_lpcmdec->p_data = DECODER_FIFO_START (*p_lpcmdec->p_fifo)->p_first; - byte_stream = lpcm_byte_stream (&p_lpcmdec->lpcm_decoder); - byte_stream->p_byte = p_lpcmdec->p_data->p_payload_start; - byte_stream->p_end = p_lpcmdec->p_data->p_payload_end; - byte_stream->info = p_lpcmdec; + vlc_mutex_unlock (&p_lpcmdec->p_fifo->data_lock); + /* Init the BitStream */ + p_lpcmdec->p_config->decoder_config.pf_init_bit_stream( + &p_lpcmdec->bit_stream, + p_lpcmdec->p_config->decoder_config.p_decoder_fifo, + NULL, NULL); /* Creating the audio output fifo */ - p_lpcmdec->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 0, 0, - LPCMDEC_FRAME_SIZE, NULL ); + p_lpcmdec->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 48000, + 0, LPCMDEC_FRAME_SIZE/2, NULL ); if ( p_lpcmdec->p_aout_fifo == NULL ) { return -1; } - - intf_DbgMsg ( "LPCM Debug: lpcm decoder thread %p initialized", p_lpcmdec ); - return 0; + intf_DbgMsg( "LPCM Debug: lpcm decoder thread %p initialized\n", + p_lpcmdec ); + return( 0 ); } /***************************************************************************** @@ -144,12 +149,8 @@ static int InitThread (lpcmdec_thread_t * p_lpcmdec) *****************************************************************************/ static void RunThread (lpcmdec_thread_t * p_lpcmdec) { - int sync; - - intf_DbgMsg( "LPCM Debug: running lpcm decoder thread (%p) (pid== %i)", p_lpcmdec, getpid() ); - - /* Fucking holy piece of shit ! */ - //msleep (INPUT_PTS_DELAY); + intf_DbgMsg( "LPCM Debug: running lpcm decoder thread (%p) (pid== %i)", + p_lpcmdec, getpid() ); /* Initializing the lpcm decoder thread */ if (InitThread (p_lpcmdec)) @@ -157,51 +158,56 @@ static void RunThread (lpcmdec_thread_t * p_lpcmdec) p_lpcmdec->p_fifo->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->p_fifo->b_die) && (!p_lpcmdec->p_fifo->b_error)) { - s16 * buffer; - lpcm_sync_info_t sync_info; - - if (!sync) - { - /* have to find a synchro point */ - } + byte_t * buffer,p_temp[LPCMDEC_FRAME_SIZE]; + int i_loop; + byte_t byte1, byte2; - if (DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts) + if( DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts ) { - p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] = DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts; + p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] = + DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts; DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts = 0; } else - { - p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] = LAST_MDATE; + { + 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)) + buffer = ((byte_t *)p_lpcmdec->p_aout_fifo->buffer) + + (p_lpcmdec->p_aout_fifo->l_end_frame * LPCMDEC_FRAME_SIZE); + + byte1 = GetBits(&p_lpcmdec->bit_stream, 8); + byte2 = GetBits(&p_lpcmdec->bit_stream, 8); + + /* Get the sync word : 0x0180 */ + while( ( byte1 != 0x01 || byte2 != 0x80 ) && (!p_lpcmdec->p_fifo->b_die) + && (!p_lpcmdec->p_fifo->b_error) ) { - sync = 0; - goto bad_frame; + byte1 = byte2; + byte2 = GetBits(&p_lpcmdec->bit_stream, 8); } - + + GetChunk( &p_lpcmdec->bit_stream, p_temp, LPCMDEC_FRAME_SIZE); + + for( i_loop = 0; i_loop < LPCMDEC_FRAME_SIZE/2; i_loop++ ) + { + buffer[2*i_loop]=p_temp[2*i_loop+1]; + buffer[2*i_loop+1]=p_temp[2*i_loop]; + } + 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; + 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); - + intf_DbgMsg( "LPCM Debug: %x", *buffer ); - bad_frame: - continue; } /* If b_error is set, the lpcm decoder thread enters the error loop */ @@ -217,56 +223,52 @@ static void RunThread (lpcmdec_thread_t * p_lpcmdec) /***************************************************************************** * ErrorThread : lpcm decoder's RunThread() error loop *****************************************************************************/ -static void ErrorThread (lpcmdec_thread_t * p_lpcmdec) +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->p_fifo->data_lock); + vlc_mutex_lock( &p_lpcmdec->p_fifo->data_lock ); /* Wait until a `die' order is sent */ - while (!p_lpcmdec->p_fifo->b_die) { + while( !p_lpcmdec->p_fifo->b_die ) + { /* Trash all received PES packets */ - while (!DECODER_FIFO_ISEMPTY(*p_lpcmdec->p_fifo)) { - p_lpcmdec->p_fifo->pf_delete_pes(p_lpcmdec->p_fifo->p_packets_mgt, - DECODER_FIFO_START(*p_lpcmdec->p_fifo)); - DECODER_FIFO_INCSTART (*p_lpcmdec->p_fifo); + while( !DECODER_FIFO_ISEMPTY(*p_lpcmdec->p_fifo) ) + { + p_lpcmdec->p_fifo->pf_delete_pes( p_lpcmdec->p_fifo->p_packets_mgt, + DECODER_FIFO_START(*p_lpcmdec->p_fifo )); + DECODER_FIFO_INCSTART( *p_lpcmdec->p_fifo ); } /* Waiting for the input thread to put new PES packets in the fifo */ - vlc_cond_wait (&p_lpcmdec->p_fifo->data_wait, &p_lpcmdec->p_fifo->data_lock); + vlc_cond_wait ( &p_lpcmdec->p_fifo->data_wait, + &p_lpcmdec->p_fifo->data_lock ); } /* We can release the lock before leaving */ - vlc_mutex_unlock (&p_lpcmdec->p_fifo->data_lock); + vlc_mutex_unlock( &p_lpcmdec->p_fifo->data_lock ); } /***************************************************************************** * EndThread : lpcm decoder thread destruction *****************************************************************************/ -static void EndThread (lpcmdec_thread_t * p_lpcmdec) +static void EndThread( lpcmdec_thread_t * p_lpcmdec ) { intf_DbgMsg( "LPCM Debug: destroying lpcm decoder thread %p", 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); + 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)); + 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); + free( p_lpcmdec ); intf_DbgMsg( "LPCM Debug: lpcm decoder thread %p destroyed", 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 */ -} diff --git a/src/lpcm_decoder/lpcm_decoder_thread.h b/src/lpcm_decoder/lpcm_decoder_thread.h index 30b95b449a..0a171e584c 100644 --- a/src/lpcm_decoder/lpcm_decoder_thread.h +++ b/src/lpcm_decoder/lpcm_decoder_thread.h @@ -2,7 +2,7 @@ * lpcm_decoder_thread.h : lpcm decoder thread interface ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: lpcm_decoder_thread.h,v 1.5 2001/05/01 04:18:18 sam Exp $ + * $Id: lpcm_decoder_thread.h,v 1.6 2001/06/12 13:50:09 henri Exp $ * * Authors: Samuel Hocevar * @@ -22,6 +22,8 @@ * Boston, MA 02111-1307, USA. *****************************************************************************/ +#define LPCMDEC_FRAME_SIZE (2008) + /***************************************************************************** * lpcmdec_thread_t : lpcm decoder thread descriptor *****************************************************************************/ @@ -40,20 +42,17 @@ typedef struct lpcmdec_thread_s int sync_ptr; /* sync ptr from lpcm magic header */ adec_config_t * p_config; - /* - * Decoder properties - */ - lpcmdec_t lpcm_decoder; - /* * Output properties */ aout_fifo_t * p_aout_fifo; /* stores the decompressed audio frames */ + /* The bit stream structure handles the PES stream at the bit level */ + bit_stream_t bit_stream; + } lpcmdec_thread_t; /***************************************************************************** * Prototypes *****************************************************************************/ vlc_thread_t lpcmdec_CreateThread( adec_config_t * p_config ); - -- 2.39.2