1
/*****************************************************************************
2
* lpcm_decoder_thread.c: lpcm decoder thread
3
*****************************************************************************
4
* Copyright (C) 1999-2001 VideoLAN
5
* $Id: lpcm_adec.c,v 1.3 2001/12/03 16:18:37 sam 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
#define MODULE_NAME lpcm_adec
26
#include "modules_inner.h"
28
/*****************************************************************************
30
*****************************************************************************/
34
#include <unistd.h> /* getpid() */
37
#include <stdio.h> /* "intf_msg.h" */
38
#include <string.h> /* memcpy(), memset() */
39
#include <stdlib.h> /* malloc(), free() */
43
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
47
#include "audio_output.h"
50
#include "modules_export.h"
52
#include "stream_control.h"
53
#include "input_ext-dec.h"
55
#include "lpcm_adec.h"
57
/*****************************************************************************
59
*****************************************************************************/
60
static int lpcm_adec_Probe ( probedata_t * );
61
static int lpcm_adec_Run ( decoder_config_t * );
62
void lpcm_adec_DecodeFrame ( lpcmdec_thread_t * );
63
static int lpcm_adec_Init ( lpcmdec_thread_t * );
64
static void lpcm_adec_ErrorThread ( lpcmdec_thread_t * );
65
static void lpcm_adec_EndThread ( lpcmdec_thread_t * );
68
/*****************************************************************************
70
*****************************************************************************/
71
void _M( adec_getfunctions )( function_list_t * p_function_list )
73
p_function_list->pf_probe = lpcm_adec_Probe;
74
p_function_list->functions.dec.pf_run = lpcm_adec_Run;
77
/*****************************************************************************
78
* Build configuration tree.
79
*****************************************************************************/
81
ADD_WINDOW( "Configuration for lpcm audio decoder module" )
82
ADD_COMMENT( "Nothing to configure" )
86
p_module->i_capabilities = MODULE_CAPABILITY_DEC;
87
p_module->psz_longname = "Linear PCM audio decoder";
91
_M( adec_getfunctions )( &p_module->p_functions->dec );
94
MODULE_DEACTIVATE_START
95
MODULE_DEACTIVATE_STOP
97
/*****************************************************************************
98
* lpcm_adec_Probe: probe the decoder and return score
99
*****************************************************************************/
100
static int lpcm_adec_Probe( probedata_t *p_data )
102
if( p_data->i_type == LPCM_AUDIO_ES )
108
/*****************************************************************************
109
* lpcm_adec_Run: the lpcm decoder
110
*****************************************************************************/
111
static int lpcm_adec_Run( decoder_config_t * p_config )
113
lpcmdec_thread_t * p_lpcmdec;
115
intf_DbgMsg("lpcm_adec debug: thread launched, initializing.");
117
/* Allocate the memory needed to store the thread's structure */
118
if( (p_lpcmdec = (lpcmdec_thread_t *)malloc (sizeof(lpcmdec_thread_t)) )
121
intf_ErrMsg( "LPCM : error : cannot create lpcmdec_thread_t" );
126
* Initialize the thread properties
128
p_lpcmdec->p_config = p_config;
129
p_lpcmdec->p_fifo = p_config->p_decoder_fifo;
131
if( lpcm_adec_Init( p_lpcmdec ) )
136
intf_DbgMsg( "LPCM Debug: lpcm decoder thread %p initialized\n",
139
/* lpcm decoder thread's main loop */
140
while ((!p_lpcmdec->p_fifo->b_die) && (!p_lpcmdec->p_fifo->b_error))
142
lpcm_adec_DecodeFrame(p_lpcmdec);
145
/* If b_error is set, the lpcm decoder thread enters the error loop */
146
if (p_lpcmdec->p_fifo->b_error)
148
lpcm_adec_ErrorThread (p_lpcmdec);
151
/* End of the lpcm decoder thread */
152
lpcm_adec_EndThread (p_lpcmdec);
157
/*****************************************************************************
158
* lpcm_adec_Init : initialize an lpcm decoder thread
159
*****************************************************************************/
160
static int lpcm_adec_Init (lpcmdec_thread_t * p_lpcmdec)
163
/* Init the BitStream */
164
p_lpcmdec->p_config->pf_init_bit_stream(
165
&p_lpcmdec->bit_stream,
166
p_lpcmdec->p_config->p_decoder_fifo,
169
/* Creating the audio output fifo */
170
p_lpcmdec->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 48000,
171
0, LPCMDEC_FRAME_SIZE/2, NULL );
172
if ( p_lpcmdec->p_aout_fifo == NULL )
179
/*****************************************************************************
180
* lpcm_adec_DecodeFrame: decodes a frame.
181
*****************************************************************************/
182
void lpcm_adec_DecodeFrame( lpcmdec_thread_t * p_lpcmdec )
184
byte_t * buffer,p_temp[LPCMDEC_FRAME_SIZE];
188
if( DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts )
190
p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] =
191
DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts;
192
DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts = 0;
196
p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] =
200
buffer = ((byte_t *)p_lpcmdec->p_aout_fifo->buffer) +
201
(p_lpcmdec->p_aout_fifo->l_end_frame * LPCMDEC_FRAME_SIZE);
203
RemoveBits32(&p_lpcmdec->bit_stream);
204
byte1 = GetBits(&p_lpcmdec->bit_stream, 8) ;
205
byte2 = GetBits(&p_lpcmdec->bit_stream, 8) ;
207
/* I only have 2 test streams. As far as I understand
208
* after the RemoveBits and the 2 GetBits, we should be exactly
209
* where we whant : the sync word : 0x0180.
210
* If not, we got and find it. */
211
while( ( byte1 != 0x01 || byte2 != 0x80 ) && (!p_lpcmdec->p_fifo->b_die)
212
&& (!p_lpcmdec->p_fifo->b_error) )
215
byte2 = GetBits(&p_lpcmdec->bit_stream, 8);
218
GetChunk( &p_lpcmdec->bit_stream, p_temp, LPCMDEC_FRAME_SIZE);
220
for( i_loop = 0; i_loop < LPCMDEC_FRAME_SIZE/2; i_loop++ )
222
buffer[2*i_loop]=p_temp[2*i_loop+1];
223
buffer[2*i_loop+1]=p_temp[2*i_loop];
226
vlc_mutex_lock (&p_lpcmdec->p_aout_fifo->data_lock);
227
p_lpcmdec->p_aout_fifo->l_end_frame =
228
(p_lpcmdec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
229
vlc_cond_signal (&p_lpcmdec->p_aout_fifo->data_wait);
230
vlc_mutex_unlock (&p_lpcmdec->p_aout_fifo->data_lock);
232
intf_DbgMsg( "LPCM Debug: %x", *buffer );
237
/*****************************************************************************
238
* lpcm_adec_ErrorThread : lpcm decoder's RunThread() error loop
239
*****************************************************************************/
240
static void lpcm_adec_ErrorThread( lpcmdec_thread_t * p_lpcmdec )
242
/* We take the lock, because we are going to read/write the start/end
243
* indexes of the decoder fifo */
244
vlc_mutex_lock( &p_lpcmdec->p_fifo->data_lock );
246
/* Wait until a `die' order is sent */
247
while( !p_lpcmdec->p_fifo->b_die )
249
/* Trash all received PES packets */
250
while( !DECODER_FIFO_ISEMPTY(*p_lpcmdec->p_fifo) )
252
p_lpcmdec->p_fifo->pf_delete_pes( p_lpcmdec->p_fifo->p_packets_mgt,
253
DECODER_FIFO_START(*p_lpcmdec->p_fifo ));
254
DECODER_FIFO_INCSTART( *p_lpcmdec->p_fifo );
257
/* Waiting for the input thread to put new PES packets in the fifo */
258
vlc_cond_wait ( &p_lpcmdec->p_fifo->data_wait,
259
&p_lpcmdec->p_fifo->data_lock );
262
/* We can release the lock before leaving */
263
vlc_mutex_unlock( &p_lpcmdec->p_fifo->data_lock );
266
/*****************************************************************************
267
* lpcm_adec_EndThread : lpcm decoder thread destruction
268
*****************************************************************************/
269
static void lpcm_adec_EndThread( lpcmdec_thread_t * p_lpcmdec )
271
intf_DbgMsg( "LPCM Debug: destroying lpcm decoder thread %p", p_lpcmdec );
273
/* If the audio output fifo was created, we destroy it */
274
if( p_lpcmdec->p_aout_fifo != NULL )
276
aout_DestroyFifo( p_lpcmdec->p_aout_fifo );
278
/* Make sure the output thread leaves the NextFrame() function */
279
vlc_mutex_lock( &(p_lpcmdec->p_aout_fifo->data_lock) );
280
vlc_cond_signal( &(p_lpcmdec->p_aout_fifo->data_wait) );
281
vlc_mutex_unlock( &(p_lpcmdec->p_aout_fifo->data_lock) );
284
/* Destroy descriptor */
287
intf_DbgMsg( "LPCM Debug: lpcm decoder thread %p destroyed", p_lpcmdec );