~ubuntu-branches/debian/wheezy/vlc/wheezy

« back to all changes in this revision

Viewing changes to plugins/lpcm_adec/lpcm_adec.c

Tags: upstream-0.7.2.final
ImportĀ upstreamĀ versionĀ 0.7.2.final

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 $
6
 
 *
7
 
 * Authors: Samuel Hocevar <sam@zoy.org>
8
 
 *          Henri Fallon <henri@videolan.org>
9
 
 *
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.
14
 
 * 
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.
19
 
 *
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
 
 *****************************************************************************/
24
 
 
25
 
#define MODULE_NAME lpcm_adec
26
 
#include "modules_inner.h"
27
 
 
28
 
/*****************************************************************************
29
 
 * Preamble
30
 
 *****************************************************************************/
31
 
#include "defs.h"
32
 
 
33
 
#ifdef HAVE_UNISTD_H
34
 
#include <unistd.h>                                              /* getpid() */
35
 
#endif
36
 
 
37
 
#include <stdio.h>                                           /* "intf_msg.h" */
38
 
#include <string.h>                                    /* memcpy(), memset() */
39
 
#include <stdlib.h>                                      /* malloc(), free() */
40
 
 
41
 
#include "config.h"
42
 
#include "common.h"
43
 
#include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
44
 
#include "threads.h"
45
 
#include "mtime.h"
46
 
 
47
 
#include "audio_output.h"
48
 
 
49
 
#include "modules.h"
50
 
#include "modules_export.h"
51
 
 
52
 
#include "stream_control.h"
53
 
#include "input_ext-dec.h"
54
 
 
55
 
#include "lpcm_adec.h"
56
 
 
57
 
/*****************************************************************************
58
 
 * Local prototypes
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 * );
66
 
 
67
 
 
68
 
/*****************************************************************************
69
 
 * Capabilities
70
 
 *****************************************************************************/
71
 
void _M( adec_getfunctions )( function_list_t * p_function_list )
72
 
{
73
 
    p_function_list->pf_probe = lpcm_adec_Probe;
74
 
    p_function_list->functions.dec.pf_run = lpcm_adec_Run;
75
 
}
76
 
 
77
 
/*****************************************************************************
78
 
 * Build configuration tree.
79
 
 *****************************************************************************/
80
 
MODULE_CONFIG_START
81
 
ADD_WINDOW( "Configuration for lpcm audio decoder module" )
82
 
    ADD_COMMENT( "Nothing to configure" )
83
 
MODULE_CONFIG_STOP
84
 
 
85
 
MODULE_INIT_START
86
 
    p_module->i_capabilities = MODULE_CAPABILITY_DEC;
87
 
    p_module->psz_longname = "Linear PCM audio decoder";
88
 
MODULE_INIT_STOP
89
 
 
90
 
MODULE_ACTIVATE_START
91
 
    _M( adec_getfunctions )( &p_module->p_functions->dec );
92
 
MODULE_ACTIVATE_STOP
93
 
 
94
 
MODULE_DEACTIVATE_START
95
 
MODULE_DEACTIVATE_STOP
96
 
 
97
 
/*****************************************************************************
98
 
 * lpcm_adec_Probe: probe the decoder and return score
99
 
 *****************************************************************************/
100
 
static int lpcm_adec_Probe( probedata_t *p_data )
101
 
{
102
 
    if( p_data->i_type == LPCM_AUDIO_ES )
103
 
        return( 100 );
104
 
    else
105
 
        return( 0 );
106
 
}
107
 
 
108
 
/*****************************************************************************
109
 
 * lpcm_adec_Run: the lpcm decoder
110
 
 *****************************************************************************/
111
 
static int lpcm_adec_Run( decoder_config_t * p_config )
112
 
{
113
 
    lpcmdec_thread_t *   p_lpcmdec;
114
 
 
115
 
    intf_DbgMsg("lpcm_adec debug: thread launched, initializing.");
116
 
    
117
 
    /* Allocate the memory needed to store the thread's structure */
118
 
    if( (p_lpcmdec = (lpcmdec_thread_t *)malloc (sizeof(lpcmdec_thread_t)) )
119
 
            == NULL) 
120
 
    {
121
 
        intf_ErrMsg( "LPCM : error : cannot create lpcmdec_thread_t" );
122
 
        return( -1 );
123
 
    }
124
 
 
125
 
    /*
126
 
     * Initialize the thread properties
127
 
     */
128
 
    p_lpcmdec->p_config = p_config;
129
 
    p_lpcmdec->p_fifo = p_config->p_decoder_fifo;
130
 
 
131
 
    if( lpcm_adec_Init( p_lpcmdec ) )
132
 
    {
133
 
        return( -1 );
134
 
    }
135
 
 
136
 
    intf_DbgMsg( "LPCM Debug: lpcm decoder thread %p initialized\n", 
137
 
                 p_lpcmdec );
138
 
    
139
 
    /* lpcm decoder thread's main loop */
140
 
    while ((!p_lpcmdec->p_fifo->b_die) && (!p_lpcmdec->p_fifo->b_error))
141
 
    {
142
 
        lpcm_adec_DecodeFrame(p_lpcmdec);
143
 
    }
144
 
 
145
 
    /* If b_error is set, the lpcm decoder thread enters the error loop */
146
 
    if (p_lpcmdec->p_fifo->b_error)
147
 
    {
148
 
        lpcm_adec_ErrorThread (p_lpcmdec);
149
 
    }
150
 
 
151
 
    /* End of the lpcm decoder thread */
152
 
    lpcm_adec_EndThread (p_lpcmdec);
153
 
 
154
 
    return( 0 );
155
 
}
156
 
 
157
 
/*****************************************************************************
158
 
 * lpcm_adec_Init : initialize an lpcm decoder thread
159
 
 *****************************************************************************/
160
 
static int lpcm_adec_Init (lpcmdec_thread_t * p_lpcmdec)
161
 
{
162
 
 
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,
167
 
            NULL, NULL);
168
 
 
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 )
173
 
    {
174
 
        return( -1 );
175
 
    }
176
 
    return( 0 );
177
 
}
178
 
 
179
 
/*****************************************************************************
180
 
 * lpcm_adec_DecodeFrame: decodes a frame.
181
 
 *****************************************************************************/
182
 
void lpcm_adec_DecodeFrame( lpcmdec_thread_t * p_lpcmdec )
183
 
{
184
 
    byte_t * buffer,p_temp[LPCMDEC_FRAME_SIZE];
185
 
    int i_loop;
186
 
    byte_t byte1, byte2;
187
 
 
188
 
    if( DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts )
189
 
    {
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;
193
 
    }
194
 
    else
195
 
    { 
196
 
        p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] =
197
 
            LAST_MDATE;
198
 
    }
199
 
 
200
 
    buffer = ((byte_t *)p_lpcmdec->p_aout_fifo->buffer) + 
201
 
              (p_lpcmdec->p_aout_fifo->l_end_frame * LPCMDEC_FRAME_SIZE);
202
 
 
203
 
    RemoveBits32(&p_lpcmdec->bit_stream);
204
 
    byte1 = GetBits(&p_lpcmdec->bit_stream, 8) ;
205
 
    byte2 = GetBits(&p_lpcmdec->bit_stream, 8) ;
206
 
    
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) )
213
 
    {
214
 
        byte1 = byte2;
215
 
        byte2 = GetBits(&p_lpcmdec->bit_stream, 8);
216
 
    }
217
 
    
218
 
    GetChunk( &p_lpcmdec->bit_stream, p_temp, LPCMDEC_FRAME_SIZE);
219
 
    
220
 
    for( i_loop = 0; i_loop < LPCMDEC_FRAME_SIZE/2; i_loop++ )
221
 
    {
222
 
        buffer[2*i_loop]=p_temp[2*i_loop+1];
223
 
        buffer[2*i_loop+1]=p_temp[2*i_loop];
224
 
    }
225
 
    
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);
231
 
    
232
 
    intf_DbgMsg( "LPCM Debug: %x", *buffer );
233
 
 
234
 
}
235
 
 
236
 
 
237
 
/*****************************************************************************
238
 
 * lpcm_adec_ErrorThread : lpcm decoder's RunThread() error loop
239
 
 *****************************************************************************/
240
 
static void lpcm_adec_ErrorThread( lpcmdec_thread_t * p_lpcmdec )
241
 
{
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 );
245
 
 
246
 
    /* Wait until a `die' order is sent */
247
 
    while( !p_lpcmdec->p_fifo->b_die ) 
248
 
    {
249
 
        /* Trash all received PES packets */
250
 
        while( !DECODER_FIFO_ISEMPTY(*p_lpcmdec->p_fifo) ) 
251
 
        {
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 );
255
 
        }
256
 
 
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 );
260
 
    }
261
 
 
262
 
    /* We can release the lock before leaving */
263
 
    vlc_mutex_unlock( &p_lpcmdec->p_fifo->data_lock );
264
 
}
265
 
 
266
 
/*****************************************************************************
267
 
 * lpcm_adec_EndThread : lpcm decoder thread destruction
268
 
 *****************************************************************************/
269
 
static void lpcm_adec_EndThread( lpcmdec_thread_t * p_lpcmdec )
270
 
{
271
 
    intf_DbgMsg( "LPCM Debug: destroying lpcm decoder thread %p", p_lpcmdec );
272
 
 
273
 
    /* If the audio output fifo was created, we destroy it */
274
 
    if( p_lpcmdec->p_aout_fifo != NULL ) 
275
 
    {
276
 
        aout_DestroyFifo( p_lpcmdec->p_aout_fifo );
277
 
 
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) );
282
 
    }
283
 
 
284
 
    /* Destroy descriptor */
285
 
    free( p_lpcmdec );
286
 
 
287
 
    intf_DbgMsg( "LPCM Debug: lpcm decoder thread %p destroyed", p_lpcmdec );
288
 
}