1 /*****************************************************************************
2 * lpcm.c: lpcm decoder module
3 *****************************************************************************
4 * Copyright (C) 1999-2001 VideoLAN
5 * $Id: lpcm.c,v 1.4 2002/09/18 01:28:05 henri Exp $
7 * Authors: Samuel Hocevar <sam@zoy.org>
8 * Henri Fallon <henri@videolan.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
28 #include <stdlib.h> /* malloc(), free() */
29 #include <string.h> /* memcpy(), memset() */
33 #include <vlc/decoder.h>
34 #include <input_ext-dec.h>
37 # include <unistd.h> /* getpid() */
41 /*****************************************************************************
43 *****************************************************************************/
44 static int OpenDecoder ( vlc_object_t * );
45 static int RunDecoder ( decoder_fifo_t * );
47 void DecodeFrame ( lpcmdec_thread_t * );
48 // static int InitThread ( lpcmdec_thread_t * );
49 static void EndThread ( lpcmdec_thread_t * );
51 /*****************************************************************************
53 *****************************************************************************/
55 set_description( _("linear PCM audio decoder") );
56 set_capability( "decoder", 100 );
57 set_callbacks( OpenDecoder, NULL );
60 /*****************************************************************************
61 * OpenDecoder: probe the decoder and return score
62 *****************************************************************************/
63 static int OpenDecoder( vlc_object_t *p_this )
65 decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
67 if( p_fifo->i_fourcc != VLC_FOURCC('l','p','c','m')
68 && p_fifo->i_fourcc != VLC_FOURCC('l','p','c','b') )
73 p_fifo->pf_run = RunDecoder;
77 /*****************************************************************************
78 * RunDecoder: the lpcm decoder
79 *****************************************************************************/
80 static int RunDecoder( decoder_fifo_t * p_fifo )
82 lpcmdec_thread_t * p_lpcmdec;
84 /* Allocate the memory needed to store the thread's structure */
85 if( (p_lpcmdec = (lpcmdec_thread_t *)malloc (sizeof(lpcmdec_thread_t)) )
88 msg_Err( p_fifo, "out of memory" );
89 DecoderError( p_fifo );
94 * Initialize the thread properties
96 p_lpcmdec->p_fifo = p_fifo;
98 /* Init the BitStream */
99 InitBitstream( &p_lpcmdec->bit_stream, p_lpcmdec->p_fifo,
102 /* FIXME : I suppose the number of channel ans sampling rate
103 * are someway in the headers */
104 p_lpcmdec->output_format.i_format = AOUT_FMT_S16_BE;
105 p_lpcmdec->output_format.i_channels = 2;
106 p_lpcmdec->output_format.i_rate = 48000;
108 aout_DateInit( &p_lpcmdec->end_date, 48000 );
109 p_lpcmdec->p_aout_input = aout_InputNew( p_lpcmdec->p_fifo,
111 &p_lpcmdec->output_format );
113 if( p_lpcmdec->p_aout_input == NULL )
115 msg_Err( p_lpcmdec->p_fifo, "failed to create aout fifo" );
116 p_lpcmdec->p_fifo->b_error = 1;
120 /* lpcm decoder thread's main loop */
121 while ((!p_lpcmdec->p_fifo->b_die) && (!p_lpcmdec->p_fifo->b_error))
123 DecodeFrame(p_lpcmdec);
126 /* If b_error is set, the lpcm decoder thread enters the error loop */
127 if (p_lpcmdec->p_fifo->b_error)
129 DecoderError( p_lpcmdec->p_fifo );
132 /* End of the lpcm decoder thread */
133 EndThread (p_lpcmdec);
138 /*****************************************************************************
139 * DecodeFrame: decodes a frame.
140 *****************************************************************************/
141 void DecodeFrame( lpcmdec_thread_t * p_lpcmdec )
143 byte_t buffer[LPCMDEC_FRAME_SIZE];
145 aout_buffer_t * p_aout_buffer;
150 NextPTS( &p_lpcmdec->bit_stream, &i_pts, NULL );
152 if( i_pts != 0 && i_pts != aout_DateGet( &p_lpcmdec->end_date ) )
154 aout_DateSet( &p_lpcmdec->end_date, i_pts );
157 p_aout_buffer = aout_BufferNew( p_lpcmdec->p_aout,
158 p_lpcmdec->p_aout_input,
159 LPCMDEC_FRAME_SIZE/4 );
163 msg_Err( p_lpcmdec->p_fifo, "cannot get aout buffer" );
164 p_lpcmdec->p_fifo->b_error = 1;
168 p_aout_buffer->start_date = aout_DateGet( &p_lpcmdec->end_date );
170 p_aout_buffer->end_date = aout_DateIncrement( &p_lpcmdec->end_date,
171 LPCMDEC_FRAME_SIZE/4 );
174 while( ( !p_lpcmdec->p_fifo->b_die ) &&
175 ( !p_lpcmdec->p_fifo->b_error ) &&
178 while( ( !p_lpcmdec->p_fifo->b_die ) &&
179 ( !p_lpcmdec->p_fifo->b_error ) &&
180 ( GetBits( &p_lpcmdec->bit_stream, 8 ) != 0x01 ) );
181 b_sync = ( ShowBits( &p_lpcmdec->bit_stream, 8 ) == 0x80 );
184 RemoveBits( &p_lpcmdec->bit_stream, 8 );
186 GetChunk( &p_lpcmdec->bit_stream, p_aout_buffer->p_buffer,
189 if( p_lpcmdec->p_fifo->b_die || p_lpcmdec->p_fifo->b_error )
192 aout_BufferPlay( p_lpcmdec->p_aout, p_lpcmdec->p_aout_input,
197 /*****************************************************************************
198 * EndThread : lpcm decoder thread destruction
199 *****************************************************************************/
200 static void EndThread( lpcmdec_thread_t * p_lpcmdec )
202 /* If the audio output fifo was created, we destroy it */
203 if( p_lpcmdec->p_aout_input )
205 aout_InputDelete( p_lpcmdec->p_aout, p_lpcmdec->p_aout_input );
209 /* Destroy descriptor */