]> git.sesse.net Git - vlc/blob - plugins/ac3_spdif/ac3_spdif.c
* plugins/dsp/aout_dsp.c: Added O_NONBLOCK flag to the open command,
[vlc] / plugins / ac3_spdif / ac3_spdif.c
1 /*****************************************************************************
2  * ac3_spdif.c: ac3 pass-through to external decoder with enabled soundcard
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id: ac3_spdif.c,v 1.26.2.1 2002/09/25 23:11:52 massiot Exp $
6  *
7  * Authors: Stéphane Borel <stef@via.ecp.fr>
8  *          Juha Yrjola <jyrjola@cc.hut.fi>
9  *          German Gomez Garcia <german@piraos.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>                                              /* memcpy() */
32 #include <fcntl.h>
33
34 #include <videolan/vlc.h>
35
36 #ifdef HAVE_UNISTD_H
37 #   include <unistd.h>
38 #endif
39
40 #include "audio_output.h"
41
42 #include "stream_control.h"
43 #include "input_ext-dec.h"
44
45 #include "ac3_spdif.h"
46
47 /****************************************************************************
48  * Local Prototypes
49  ****************************************************************************/
50 static int  decoder_Probe     ( u8 * );
51 static int  decoder_Run       ( decoder_config_t * );
52 static int  InitThread        ( ac3_spdif_thread_t * );
53 static void EndThread         ( ac3_spdif_thread_t * );
54 static void BitstreamCallback ( bit_stream_t *, boolean_t );
55
56 int     ac3_parse_syncinfo   ( struct ac3_spdif_thread_s * );
57
58 /****************************************************************************
59  * Local structures and tables
60  ****************************************************************************/
61 static const frame_size_t p_frame_size_code[64] =
62 {
63         { 32  ,{64   ,69   ,96   } },
64         { 32  ,{64   ,70   ,96   } },
65         { 40  ,{80   ,87   ,120  } },
66         { 40  ,{80   ,88   ,120  } },
67         { 48  ,{96   ,104  ,144  } },
68         { 48  ,{96   ,105  ,144  } },
69         { 56  ,{112  ,121  ,168  } },
70         { 56  ,{112  ,122  ,168  } },
71         { 64  ,{128  ,139  ,192  } },
72         { 64  ,{128  ,140  ,192  } },
73         { 80  ,{160  ,174  ,240  } },
74         { 80  ,{160  ,175  ,240  } },
75         { 96  ,{192  ,208  ,288  } },
76         { 96  ,{192  ,209  ,288  } },
77         { 112 ,{224  ,243  ,336  } },
78         { 112 ,{224  ,244  ,336  } },
79         { 128 ,{256  ,278  ,384  } },
80         { 128 ,{256  ,279  ,384  } },
81         { 160 ,{320  ,348  ,480  } },
82         { 160 ,{320  ,349  ,480  } },
83         { 192 ,{384  ,417  ,576  } },
84         { 192 ,{384  ,418  ,576  } },
85         { 224 ,{448  ,487  ,672  } },
86         { 224 ,{448  ,488  ,672  } },
87         { 256 ,{512  ,557  ,768  } },
88         { 256 ,{512  ,558  ,768  } },
89         { 320 ,{640  ,696  ,960  } },
90         { 320 ,{640  ,697  ,960  } },
91         { 384 ,{768  ,835  ,1152 } },
92         { 384 ,{768  ,836  ,1152 } },
93         { 448 ,{896  ,975  ,1344 } },
94         { 448 ,{896  ,976  ,1344 } },
95         { 512 ,{1024 ,1114 ,1536 } },
96         { 512 ,{1024 ,1115 ,1536 } },
97         { 576 ,{1152 ,1253 ,1728 } },
98         { 576 ,{1152 ,1254 ,1728 } },
99         { 640 ,{1280 ,1393 ,1920 } },
100         { 640 ,{1280 ,1394 ,1920 } }
101 };
102
103 /*****************************************************************************
104  * Capabilities
105  *****************************************************************************/
106 void _M( adec_getfunctions )( function_list_t * p_function_list )
107 {
108     p_function_list->functions.dec.pf_probe = decoder_Probe;
109     p_function_list->functions.dec.pf_run   = decoder_Run;
110 }
111
112 /*****************************************************************************
113  * Build configuration tree.
114  *****************************************************************************/
115 MODULE_CONFIG_START
116 MODULE_CONFIG_STOP
117
118 MODULE_INIT_START
119     SET_DESCRIPTION( _("SPDIF pass-through AC3 decoder") )
120     ADD_CAPABILITY( DECODER, 0 )
121     ADD_SHORTCUT( "ac3_spdif" )
122     ADD_SHORTCUT( "pass_through" )
123     ADD_SHORTCUT( "pass" )
124 MODULE_INIT_STOP
125
126 MODULE_ACTIVATE_START
127     _M( adec_getfunctions )( &p_module->p_functions->dec );
128 MODULE_ACTIVATE_STOP
129
130 MODULE_DEACTIVATE_START
131 MODULE_DEACTIVATE_STOP
132
133 /*****************************************************************************
134  * decoder_Probe: probe the decoder and return score
135  *****************************************************************************
136  * Tries to launch a decoder and return score so that the interface is able 
137  * to chose.
138  *****************************************************************************/
139 static int decoder_Probe( u8 *pi_type )
140 {
141     return ( (*pi_type == AC3_AUDIO_ES || *pi_type == A52B_AUDIO_ES) ? 0 : -1 );
142 }
143
144
145 /****************************************************************************
146  * decoder_Run: the whole thing
147  ****************************************************************************
148  * This function is called just after the thread is launched.
149  ****************************************************************************/
150 static int decoder_Run( decoder_config_t * p_config )
151 {
152     ac3_spdif_thread_t *   p_spdif;
153     mtime_t     i_frame_time;
154     boolean_t   b_sync;
155     /* PTS of the current frame */
156     mtime_t     i_current_pts = 0;
157     u16         i_length;
158     
159     /* Allocate the memory needed to store the thread's structure */
160     p_spdif = malloc( sizeof(ac3_spdif_thread_t) );
161
162     if( p_spdif == NULL )
163     {
164         intf_ErrMsg ( "spdif error: not enough memory "
165                       "for spdif_CreateThread() to create the new thread");
166         DecoderError( p_config->p_decoder_fifo );
167         return( -1 );
168     }
169   
170     p_spdif->p_config = p_config; 
171     
172     if (InitThread( p_spdif ) )
173     {
174         intf_ErrMsg( "spdif error: could not initialize thread" );
175         DecoderError( p_config->p_decoder_fifo );
176         free( p_spdif );
177         return( -1 );
178     }
179
180     /* Compute the theorical duration of an ac3 frame */
181     i_frame_time = 1000000 * AC3_FRAME_SIZE /
182                              p_spdif->ac3_info.i_sample_rate;
183     i_length = p_spdif->ac3_info.i_frame_size;
184     
185     while( !p_spdif->p_fifo->b_die && !p_spdif->p_fifo->b_error )
186     {
187         p_spdif->p_ac3[0] = 0x0b;
188         p_spdif->p_ac3[1] = 0x77;
189         
190          /* Handle the dates */
191         if( p_spdif->i_real_pts )
192         {
193             mtime_t     i_delta = p_spdif->i_real_pts - i_current_pts -
194                                   i_frame_time;
195             if( i_delta > i_frame_time || i_delta < -i_frame_time )
196             {
197                 intf_WarnMsg( 3, "spdif warning: date discontinuity (%d)",
198                               i_delta );
199             }
200             i_current_pts = p_spdif->i_real_pts;
201             p_spdif->i_real_pts = 0;
202         }
203         else
204         {
205             i_current_pts += i_frame_time;
206         }
207         
208         vlc_mutex_lock (&p_spdif->p_aout_fifo->data_lock);
209         
210         p_spdif->p_aout_fifo->date[p_spdif->p_aout_fifo->i_end_frame] =
211             i_current_pts;
212
213         p_spdif->p_aout_fifo->i_end_frame = 
214                 (p_spdif->p_aout_fifo->i_end_frame + 1 ) & AOUT_FIFO_SIZE;
215         
216         p_spdif->p_ac3 = ((u8*)(p_spdif->p_aout_fifo->buffer)) +
217                      (p_spdif->p_aout_fifo->i_end_frame * i_length );
218         
219         vlc_mutex_unlock (&p_spdif->p_aout_fifo->data_lock);
220
221         /* Find syncword again in case of stream discontinuity */
222         /* Here we have p_spdif->i_pts == 0
223          * Therefore a non-zero value after a call to GetBits() means the PES
224          * has changed. */
225         b_sync = 0;
226         while( !p_spdif->p_fifo->b_die
227             && !p_spdif->p_fifo->b_error
228             && !b_sync )
229         {
230             while( !p_spdif->p_fifo->b_die
231                 && !p_spdif->p_fifo->b_error
232                 && GetBits( &p_spdif->bit_stream, 8 ) != 0x0b );
233             p_spdif->i_real_pts = p_spdif->i_pts;
234             p_spdif->i_pts = 0;
235             b_sync = ( ShowBits( &p_spdif->bit_stream, 8 ) == 0x77 );
236         }
237         RemoveBits( &p_spdif->bit_stream, 8 );
238
239         /* Read data from bitstream */
240         GetChunk( &p_spdif->bit_stream, p_spdif->p_ac3 + 2, i_length - 2 );
241     }
242
243     /* If b_error is set, the ac3 spdif thread enters the error loop */
244     if( p_spdif->p_fifo->b_error )
245     {
246         DecoderError( p_spdif->p_fifo );
247     }
248
249     /* End of the ac3 decoder thread */
250     EndThread( p_spdif );
251     
252     return( 0 );
253 }
254
255 /****************************************************************************
256  * InitThread: initialize thread data and create output fifo
257  ****************************************************************************/
258 static int InitThread( ac3_spdif_thread_t * p_spdif )
259 {
260     boolean_t b_sync = 0;
261
262     /* Temporary buffer to store first ac3 frame */
263     p_spdif->p_ac3 = malloc( SPDIF_FRAME_SIZE );
264
265     if( p_spdif->p_ac3 == NULL )
266     {
267         free( p_spdif->p_ac3 );
268         return( -1 );
269     }
270
271     /*
272      * Initialize the thread properties
273      */
274     p_spdif->p_fifo = p_spdif->p_config->p_decoder_fifo;
275
276     InitBitstream( &p_spdif->bit_stream, p_spdif->p_config->p_decoder_fifo,
277                    BitstreamCallback, (void*)p_spdif );
278
279     /* Find syncword */
280     while( !p_spdif->p_fifo->b_die
281         && !p_spdif->p_fifo->b_error
282         && !b_sync )
283     {
284         while( !p_spdif->p_fifo->b_die
285             && !p_spdif->p_fifo->b_error
286             && GetBits( &p_spdif->bit_stream, 8 ) != 0x0b );
287         p_spdif->i_real_pts = p_spdif->i_pts;
288         p_spdif->i_pts = 0;
289         b_sync = ( ShowBits( &p_spdif->bit_stream, 8 ) == 0x77 );
290     }
291
292     if( p_spdif->p_fifo->b_die || p_spdif->p_fifo->b_error )
293     {
294         return -1;
295     }
296
297     RemoveBits( &p_spdif->bit_stream, 8 );
298
299     /* Check stream properties */
300     if( ac3_parse_syncinfo( p_spdif ) < 0 )
301     {
302         intf_ErrMsg( "spdif error: stream not valid");
303
304         return( -1 );
305     }
306
307     /* Check that we can handle the rate 
308      * FIXME: we should check that we have the same rate for all fifos 
309      * but all rates should be supported by the decoder (32, 44.1, 48) */
310     if( p_spdif->ac3_info.i_sample_rate != 48000 )
311     {
312         intf_ErrMsg( "spdif error: Only 48000 Hz streams tested"
313                      "expect weird things !" );
314     }
315
316     /* The audio output need to be ready for an ac3 stream */
317     p_spdif->i_previous_format = config_GetIntVariable( "audio-format" );
318     config_PutIntVariable( "audio-format", 8 );
319     
320     /* Creating the audio output fifo */
321     p_spdif->p_aout_fifo = aout_CreateFifo( AOUT_FIFO_SPDIF, 1,
322                                             p_spdif->ac3_info.i_sample_rate,
323                                             p_spdif->ac3_info.i_frame_size,
324                                             NULL );
325
326     if( p_spdif->p_aout_fifo == NULL )
327     {
328         return( -1 );
329     }
330
331     intf_WarnMsg( 3, "spdif: aout fifo #%d created",
332                      p_spdif->p_aout_fifo->i_fifo );
333
334     /* Put read data into fifo */
335     memcpy( (u8*)(p_spdif->p_aout_fifo->buffer) +
336                  (p_spdif->p_aout_fifo->i_end_frame *
337                    p_spdif->ac3_info.i_frame_size ),
338             p_spdif->p_ac3, sizeof(sync_frame_t) );
339     free( p_spdif->p_ac3 );
340     p_spdif->p_ac3 = ((u8*)(p_spdif->p_aout_fifo->buffer) +
341                            (p_spdif->p_aout_fifo->i_end_frame *
342                             p_spdif->ac3_info.i_frame_size ));
343
344     GetChunk( &p_spdif->bit_stream, p_spdif->p_ac3 + sizeof(sync_frame_t),
345         p_spdif->ac3_info.i_frame_size - sizeof(sync_frame_t) );
346
347     return( 0 );
348 }
349
350 /*****************************************************************************
351  * EndThread : ac3 spdif thread destruction
352  *****************************************************************************/
353 static void EndThread( ac3_spdif_thread_t * p_spdif )
354 {
355     /* If the audio output fifo was created, we destroy it */
356     if( p_spdif->p_aout_fifo != NULL )
357     {
358         aout_DestroyFifo( p_spdif->p_aout_fifo );
359
360         /* Make sure the output thread leaves the NextFrame() function */
361         vlc_mutex_lock( &(p_spdif->p_aout_fifo->data_lock ) );
362         vlc_cond_signal( &(p_spdif->p_aout_fifo->data_wait ) );
363         vlc_mutex_unlock( &(p_spdif->p_aout_fifo->data_lock ) );
364         
365     }
366
367     /* restore previous setting for output format */
368     config_PutIntVariable( "audio-format", p_spdif->i_previous_format );
369
370     /* Destroy descriptor */
371     free( p_spdif );
372 }
373
374 /*****************************************************************************
375  * BitstreamCallback: Import parameters from the new data/PES packet
376  *****************************************************************************
377  * This function is called by input's NextDataPacket.
378  *****************************************************************************/
379 static void BitstreamCallback( bit_stream_t * p_bit_stream,
380                                boolean_t      b_new_pes )
381 {
382     ac3_spdif_thread_t *    p_spdif;
383
384     if( b_new_pes )
385     {
386         p_spdif = (ac3_spdif_thread_t *)p_bit_stream->p_callback_arg;
387
388 /*        p_bit_stream->p_byte += 3; */
389
390         p_spdif->i_pts =
391             p_bit_stream->p_decoder_fifo->p_first->i_pts;
392         p_bit_stream->p_decoder_fifo->p_first->i_pts = 0;
393     }
394 }
395
396 /****************************************************************************
397  * ac3_parse_syncinfo: parse ac3 sync info
398  ****************************************************************************/
399 int ac3_parse_syncinfo( ac3_spdif_thread_t *p_spdif )
400 {
401     int             p_sample_rates[4] = { 48000, 44100, 32000, -1 };
402     int             i_frame_rate_code;
403     int             i_frame_size_code;
404     sync_frame_t *  p_sync_frame;
405
406     /* Read sync frame */
407     GetChunk( &p_spdif->bit_stream, p_spdif->p_ac3 + 2,
408               sizeof(sync_frame_t) - 2 );
409     if( p_spdif->p_fifo->b_die ) return -1;
410
411     p_sync_frame = (sync_frame_t*)p_spdif->p_ac3;
412
413     /* Compute frame rate */
414     i_frame_rate_code = (p_sync_frame->syncinfo.code >> 6) & 0x03;
415     p_spdif->ac3_info.i_sample_rate = p_sample_rates[i_frame_rate_code];
416     if( p_spdif->ac3_info.i_sample_rate == -1 )
417     {
418         return -1;
419     }
420
421     /* Compute frame size */
422     i_frame_size_code = p_sync_frame->syncinfo.code & 0x3f;
423     p_spdif->ac3_info.i_frame_size = 2 *
424         p_frame_size_code[i_frame_size_code].i_frame_size[i_frame_rate_code];
425     p_spdif->ac3_info.i_bit_rate =
426         p_frame_size_code[i_frame_size_code].i_bit_rate;
427
428     if( ( ( p_sync_frame->bsi.bsidmod >> 3 ) & 0x1f ) != 0x08 )
429     {
430         return -1;
431     }
432
433     p_spdif->ac3_info.i_bs_mod = p_sync_frame->bsi.bsidmod & 0x7;
434
435     return 0;
436 }