]> git.sesse.net Git - vlc/blob - modules/codec/lpcm.c
Merge branch 'master' into lpcm_encoder
[vlc] / modules / codec / lpcm.c
1 /*****************************************************************************
2  * lpcm.c: lpcm decoder/packetizer module
3  *****************************************************************************
4  * Copyright (C) 1999-2008 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Samuel Hocevar <sam@zoy.org>
8  *          Henri Fallon <henri@videolan.org>
9  *          Christophe Massiot <massiot@via.ecp.fr>
10  *          Gildas Bazin <gbazin@videolan.org>
11  *          Lauren Aimar <fenrir _AT_ videolan _DOT_ org >
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26  *****************************************************************************/
27
28 /*****************************************************************************
29  * Preamble
30  *****************************************************************************/
31 #ifdef HAVE_CONFIG_H
32 # include "config.h"
33 #endif
34
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_codec.h>
38 #include <vlc_aout.h>
39 #include <assert.h>
40
41 /*****************************************************************************
42  * Module descriptor
43  *****************************************************************************/
44 static int  OpenDecoder   ( vlc_object_t * );
45 static int  OpenPacketizer( vlc_object_t * );
46 static void CloseCommon   ( vlc_object_t * );
47
48 #ifdef ENABLE_SOUT
49 static int  OpenEncoder   ( vlc_object_t * );
50 static void CloseEncoder  ( vlc_object_t * );
51 static block_t *EncoderEncode( encoder_t *, aout_buffer_t * );
52 #endif
53
54 vlc_module_begin ()
55
56     set_category( CAT_INPUT )
57     set_subcategory( SUBCAT_INPUT_ACODEC )
58     set_description( N_("Linear PCM audio decoder") )
59     set_capability( "decoder", 100 )
60     set_callbacks( OpenDecoder, CloseCommon )
61
62     add_submodule ()
63     set_description( N_("Linear PCM audio packetizer") )
64     set_capability( "packetizer", 100 )
65     set_callbacks( OpenPacketizer, CloseCommon )
66
67     add_submodule ()
68     set_description( N_("Linear PCM audio encoder") )
69     set_capability( "encoder", 100 )
70     set_callbacks( OpenEncoder, CloseEncoder )
71     add_shortcut( "lpcm" )
72
73 vlc_module_end ()
74
75
76 /*****************************************************************************
77  * decoder_sys_t : lpcm decoder descriptor
78  *****************************************************************************/
79 struct decoder_sys_t
80 {
81     /* Module mode */
82     bool b_packetizer;
83
84     /*
85      * Output properties
86      */
87     date_t   end_date;
88
89     /* */
90     unsigned i_header_size;
91     int      i_type;
92 };
93
94 struct encoder_sys_t
95 {
96     int     i_channels;
97     int     i_rate;
98
99     int     i_frame_samples;
100     uint8_t *p_buffer;
101     int     i_buffer_used;
102     int     i_frame_num;
103 };
104
105 /*
106  * LPCM DVD header :
107  * - number of frames in this packet (8 bits)
108  * - first access unit (16 bits) == 0x0003 ?
109  * - emphasis (1 bit)
110  * - mute (1 bit)
111  * - reserved (1 bit)
112  * - current frame (5 bits)
113  * - quantisation (2 bits) 0 == 16bps, 1 == 20bps, 2 == 24bps, 3 == illegal
114  * - frequency (2 bits) 0 == 48 kHz, 1 == 96 kHz, 2 == 44.1 kHz, 3 == 32 kHz
115  * - reserved (1 bit)
116  * - number of channels - 1 (3 bits) 1 == 2 channels
117  * - dynamic range (8 bits) 0x80 == neutral
118  *
119  * LPCM DVD-A header (http://dvd-audio.sourceforge.net/spec/aob.shtml)
120  * - continuity counter (8 bits, clipped to 0x00-0x1f)
121  * - header size (16 bits)
122  * - byte pointer to start of first audio frame.
123  * - unknown (8bits, 0x10 for stereo, 0x00 for surround)
124  * - sample size (4+4 bits)
125  * - samplerate (4+4 bits)
126  * - unknown (8 bits)
127  * - group assignment (8 bits)
128  * - unknown (8 bits)
129  * - padding(variable)
130  *
131  * LPCM BD header :
132  * - unkown (16 bits)
133  * - number of channels (4 bits)
134  * - frequency (4 bits)
135  * - bits per sample (2 bits)
136  * - unknown (6 bits)
137  */
138
139 #define LPCM_VOB_HEADER_LEN (6)
140 #define LPCM_AOB_HEADER_LEN (11)
141 #define LPCM_BD_HEADER_LEN (4)
142
143 enum
144 {
145     LPCM_VOB,
146     LPCM_AOB,
147     LPCM_BD,
148 };
149
150 typedef struct
151 {
152     unsigned i_channels;
153     bool     b_used;
154     unsigned pi_position[6];
155 } aob_group_t;
156
157 /*****************************************************************************
158  * Local prototypes
159  *****************************************************************************/
160 static void *DecodeFrame  ( decoder_t *, block_t ** );
161
162 /* */
163 static int VobHeader( unsigned *pi_rate,
164                       unsigned *pi_channels, unsigned *pi_original_channels,
165                       unsigned *pi_bits,
166                       const uint8_t *p_header );
167 static void VobExtract( aout_buffer_t *, block_t *, unsigned i_bits );
168 /* */
169 static int AobHeader( unsigned *pi_rate,
170                       unsigned *pi_channels, unsigned *pi_layout,
171                       unsigned *pi_bits,
172                       unsigned *pi_padding,
173                       aob_group_t g[2],
174                       const uint8_t *p_header );
175 static void AobExtract( aout_buffer_t *, block_t *, unsigned i_bits, aob_group_t p_group[2] );
176 /* */
177 static int BdHeader( unsigned *pi_rate,
178                      unsigned *pi_channels, unsigned *pi_original_channels,
179                      unsigned *pi_bits,
180                      const uint8_t *p_header );
181 static void BdExtract( aout_buffer_t *, block_t * );
182
183
184 /*****************************************************************************
185  * OpenCommon:
186  *****************************************************************************/
187 static int OpenCommon( vlc_object_t *p_this, bool b_packetizer )
188 {
189     decoder_t *p_dec = (decoder_t*)p_this;
190     decoder_sys_t *p_sys;
191     int i_type;
192     int i_header_size;
193
194     switch( p_dec->fmt_in.i_codec )
195     {
196     /* DVD LPCM */
197     case VLC_CODEC_DVD_LPCM:
198         i_type = LPCM_VOB;
199         i_header_size = LPCM_VOB_HEADER_LEN;
200         break;
201     /* DVD-Audio LPCM */
202     case VLC_CODEC_DVDA_LPCM:
203         i_type = LPCM_AOB;
204         i_header_size = LPCM_AOB_HEADER_LEN;
205         break;
206     /* BD LPCM */
207     case VLC_CODEC_BD_LPCM:
208         i_type = LPCM_BD;
209         i_header_size = LPCM_BD_HEADER_LEN;
210         break;
211     default:
212         return VLC_EGENERIC;
213     }
214
215     /* Allocate the memory needed to store the decoder's structure */
216     if( ( p_dec->p_sys = p_sys = malloc(sizeof(decoder_sys_t)) ) == NULL )
217         return VLC_ENOMEM;
218
219     /* Misc init */
220     p_sys->b_packetizer = b_packetizer;
221     date_Set( &p_sys->end_date, 0 );
222     p_sys->i_type = i_type;
223     p_sys->i_header_size = i_header_size;
224
225     /* Set output properties */
226     p_dec->fmt_out.i_cat = AUDIO_ES;
227
228     if( b_packetizer )
229     {
230         switch( i_type )
231         {
232         case LPCM_VOB:
233             p_dec->fmt_out.i_codec = VLC_CODEC_DVD_LPCM;
234             break;
235         case LPCM_AOB:
236             p_dec->fmt_out.i_codec = VLC_CODEC_DVDA_LPCM;
237             break;
238         default:
239             assert(0);
240         case LPCM_BD:
241             p_dec->fmt_out.i_codec = VLC_CODEC_BD_LPCM;
242             break;
243         }
244     }
245     else
246     {
247         switch( p_dec->fmt_out.audio.i_bitspersample )
248         {
249         case 24:
250         case 20:
251             p_dec->fmt_out.i_codec = VLC_CODEC_S24B;
252             p_dec->fmt_out.audio.i_bitspersample = 24;
253             break;
254         default:
255             p_dec->fmt_out.i_codec = VLC_CODEC_S16B;
256             p_dec->fmt_out.audio.i_bitspersample = 16;
257             break;
258         }
259     }
260
261     /* Set callback */
262     p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
263         DecodeFrame;
264     p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
265         DecodeFrame;
266
267     return VLC_SUCCESS;
268 }
269 static int OpenDecoder( vlc_object_t *p_this )
270 {
271     return OpenCommon( p_this, false );
272 }
273 static int OpenPacketizer( vlc_object_t *p_this )
274 {
275     return OpenCommon( p_this, true );
276 }
277
278 /*****************************************************************************
279  * DecodeFrame: decodes an lpcm frame.
280  ****************************************************************************
281  * Beware, this function must be fed with complete frames (PES packet).
282  *****************************************************************************/
283 static void *DecodeFrame( decoder_t *p_dec, block_t **pp_block )
284 {
285     decoder_sys_t *p_sys = p_dec->p_sys;
286     block_t       *p_block;
287     unsigned int  i_rate = 0, i_original_channels = 0, i_channels = 0, i_bits = 0;
288     int           i_frame_length;
289
290     if( !pp_block || !*pp_block ) return NULL;
291
292     p_block = *pp_block;
293     *pp_block = NULL; /* So the packet doesn't get re-sent */
294
295     /* Date management */
296     if( p_block->i_pts > VLC_TS_INVALID &&
297         p_block->i_pts != date_Get( &p_sys->end_date ) )
298     {
299         date_Set( &p_sys->end_date, p_block->i_pts );
300     }
301
302     if( !date_Get( &p_sys->end_date ) )
303     {
304         /* We've just started the stream, wait for the first PTS. */
305         block_Release( p_block );
306         return NULL;
307     }
308
309     if( p_block->i_buffer <= p_sys->i_header_size )
310     {
311         msg_Err(p_dec, "frame is too short");
312         block_Release( p_block );
313         return NULL;
314     }
315
316     int i_ret;
317     unsigned i_padding = 0;
318     aob_group_t p_aob_group[2];
319     switch( p_sys->i_type )
320     {
321     case LPCM_VOB:
322         i_ret = VobHeader( &i_rate, &i_channels, &i_original_channels, &i_bits,
323                            p_block->p_buffer );
324         break;
325     case LPCM_AOB:
326         i_ret = AobHeader( &i_rate, &i_channels, &i_original_channels, &i_bits, &i_padding,
327                            p_aob_group,
328                            p_block->p_buffer );
329         break;
330     case LPCM_BD:
331         i_ret = BdHeader( &i_rate, &i_channels, &i_original_channels, &i_bits,
332                           p_block->p_buffer );
333         break;
334     default:
335         abort();
336     }
337
338     if( i_ret || p_block->i_buffer <= p_sys->i_header_size + i_padding )
339     {
340         msg_Warn( p_dec, "no frame sync or too small frame" );
341         block_Release( p_block );
342         return NULL;
343     }
344
345     /* Set output properties */
346     if( p_dec->fmt_out.audio.i_rate != i_rate )
347     {
348         date_Init( &p_sys->end_date, i_rate, 1 );
349         date_Set( &p_sys->end_date, p_block->i_pts );
350     }
351     p_dec->fmt_out.audio.i_rate = i_rate;
352     p_dec->fmt_out.audio.i_channels = i_channels;
353     p_dec->fmt_out.audio.i_original_channels = i_original_channels;
354     p_dec->fmt_out.audio.i_physical_channels = i_original_channels & AOUT_CHAN_PHYSMASK;
355
356     i_frame_length = (p_block->i_buffer - p_sys->i_header_size - i_padding) / i_channels * 8 / i_bits;
357
358     if( p_sys->b_packetizer )
359     {
360         p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date );
361         p_block->i_length =
362             date_Increment( &p_sys->end_date, i_frame_length ) -
363             p_block->i_pts;
364
365         /* Just pass on the incoming frame */
366         return p_block;
367     }
368     else
369     {
370         /* */
371         if( i_bits == 16 )
372         {
373             p_dec->fmt_out.i_codec = VLC_CODEC_S16B;
374             p_dec->fmt_out.audio.i_bitspersample = 16;
375         }
376         else
377         {
378             p_dec->fmt_out.i_codec = VLC_CODEC_S24B;
379             p_dec->fmt_out.audio.i_bitspersample = 24;
380         }
381
382         /* */
383         aout_buffer_t *p_aout_buffer;
384         p_aout_buffer = decoder_NewAudioBuffer( p_dec, i_frame_length );
385         if( !p_aout_buffer )
386             return NULL;
387
388         p_aout_buffer->i_pts = date_Get( &p_sys->end_date );
389         p_aout_buffer->i_length =
390             date_Increment( &p_sys->end_date, i_frame_length )
391             - p_aout_buffer->i_pts;
392
393         p_block->p_buffer += p_sys->i_header_size + i_padding;
394         p_block->i_buffer -= p_sys->i_header_size + i_padding;
395
396         switch( p_sys->i_type )
397         {
398         case LPCM_VOB:
399             VobExtract( p_aout_buffer, p_block, i_bits );
400             break;
401         case LPCM_AOB:
402             AobExtract( p_aout_buffer, p_block, i_bits, p_aob_group );
403             break;
404         default:
405             assert(0);
406         case LPCM_BD:
407             BdExtract( p_aout_buffer, p_block );
408             break;
409         }
410
411         block_Release( p_block );
412         return p_aout_buffer;
413     }
414 }
415
416 /*****************************************************************************
417  * CloseCommon : lpcm decoder destruction
418  *****************************************************************************/
419 static void CloseCommon( vlc_object_t *p_this )
420 {
421     decoder_t *p_dec = (decoder_t*)p_this;
422     free( p_dec->p_sys );
423 }
424
425 /*****************************************************************************
426  * OpenEncoder:
427  *****************************************************************************/
428 static int OpenEncoder( vlc_object_t *p_this )
429 {
430     encoder_t *p_enc = (encoder_t *)p_this;
431     encoder_sys_t *p_sys;
432
433     if( p_enc->fmt_out.i_codec != VLC_CODEC_DVD_LPCM ||
434         ( p_enc->fmt_in.audio.i_rate != 48000 &&
435           p_enc->fmt_in.audio.i_rate != 96000 &&
436           p_enc->fmt_in.audio.i_rate != 44100 &&
437           p_enc->fmt_in.audio.i_rate != 32000 ) ||
438        p_enc->fmt_in.audio.i_channels > 8 )
439     {
440         return VLC_EGENERIC;
441     }
442
443     /* Allocate the memory needed to store the encoder's structure */
444     if( ( p_enc->p_sys = p_sys =
445           (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
446         return VLC_ENOMEM;
447
448     p_enc->pf_encode_audio = EncoderEncode;
449     p_enc->fmt_in.i_codec = p_enc->fmt_out.i_codec;
450
451     p_enc->fmt_in.audio.i_bitspersample = 16;
452     p_enc->fmt_in.i_codec = VLC_CODEC_S16B;
453
454     p_enc->fmt_out.i_bitrate =
455         p_enc->fmt_in.audio.i_channels *
456         p_enc->fmt_in.audio.i_rate *
457         p_enc->fmt_in.audio.i_bitspersample;
458     
459     p_sys->i_channels = p_enc->fmt_in.audio.i_channels;
460     p_sys->i_rate = p_enc->fmt_in.audio.i_rate;
461     
462     /* In DVD LCPM, a frame is always 150 PTS ticks. */
463     p_sys->i_frame_samples = p_enc->fmt_in.audio.i_rate * 150 / 90000;
464     p_sys->p_buffer = (uint8_t *)malloc(
465         p_sys->i_frame_samples *
466         p_enc->fmt_in.audio.i_channels *
467         p_enc->fmt_in.audio.i_bitspersample);
468     p_sys->i_buffer_used = 0;
469     p_sys->i_frame_num = 0;
470
471     return VLC_SUCCESS;
472 }
473
474 /*****************************************************************************
475  * CloseEncoder
476  *****************************************************************************/
477 static void CloseEncoder ( vlc_object_t *p_this )
478 {
479     VLC_UNUSED(p_this);
480 }
481
482 /*****************************************************************************
483  * EncoderEncode:
484  *****************************************************************************/
485 static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
486 {
487     encoder_sys_t *p_sys = p_enc->p_sys;
488     block_t *p_first_block = NULL, *p_last_block = NULL;
489
490     if( !p_aout_buf || !p_aout_buf->i_buffer ) return NULL;
491
492     const int i_num_frames = ( p_sys->i_buffer_used + p_aout_buf->i_nb_samples ) /
493         p_sys->i_frame_samples;
494     const int i_leftover_samples = ( p_sys->i_buffer_used + p_aout_buf->i_nb_samples ) %
495         p_sys->i_frame_samples;
496     const int i_frame_size = p_sys->i_frame_samples * p_sys->i_channels * 2 + LPCM_VOB_HEADER_LEN;
497
498     uint8_t i_freq_code = 0;
499
500     switch( p_sys->i_rate ) {
501     case 48000:
502         i_freq_code = 0;
503         break;
504     case 96000:
505         i_freq_code = 1;
506         break;
507     case 44100:
508         i_freq_code = 2;
509         break;
510     case 32000:
511         i_freq_code = 3;
512         break;
513     }
514
515     int i_bytes_consumed = 0;
516
517     for ( int i = 0; i < i_num_frames; ++i )
518     {
519         block_t *p_block = block_New( p_enc, i_frame_size );
520         if( !p_block )
521             return NULL;
522
523         uint8_t *frame = (uint8_t *)p_block->p_buffer;
524         frame[0] = 1;  /* one frame in packet */
525         frame[1] = 0;
526         frame[2] = 0;  /* no first access unit */
527         frame[3] = (p_sys->i_frame_num + i) & 0x1f;  /* no emphasis, no mute */
528         frame[4] = (i_freq_code << 4) | (p_sys->i_channels - 1);
529         frame[5] = 0x80;  /* neutral dynamic range */
530
531         const int i_consume_samples = p_sys->i_frame_samples - p_sys->i_buffer_used;
532         const int i_kept_bytes = p_sys->i_buffer_used * p_sys->i_channels * 2;
533         const int i_consume_bytes = i_consume_samples * p_sys->i_channels * 2;
534
535         memcpy( frame + 6, p_sys->p_buffer, i_kept_bytes );
536         memcpy( frame + 6 + i_kept_bytes, p_aout_buf->p_buffer + i_bytes_consumed, i_consume_bytes );
537      
538         p_sys->i_frame_num++;
539         p_sys->i_buffer_used = 0;
540         i_bytes_consumed += i_consume_bytes;
541
542         /* 
543          * The pts is strictly not correct if we have samples kept from
544          * a previous buffer, but the frames are so small it should be OK.
545          */
546         p_block->i_dts = p_block->i_pts = p_aout_buf->i_pts + i * p_sys->i_frame_samples * CLOCK_FREQ / p_sys->i_rate;
547         p_block->i_length = p_sys->i_frame_samples * CLOCK_FREQ / p_sys->i_rate;
548         
549         if( !p_first_block )
550             p_first_block = p_last_block = p_block;
551         else
552             block_ChainLastAppend( &p_last_block, p_block );
553     }
554
555     memcpy( p_sys->p_buffer,
556             p_aout_buf->p_buffer + i_bytes_consumed,
557             i_leftover_samples * p_sys->i_channels * 2 );
558     p_sys->i_buffer_used = i_leftover_samples;
559
560     return p_first_block;
561 }
562
563 /*****************************************************************************
564  *
565  *****************************************************************************/
566 static int VobHeader( unsigned *pi_rate,
567                       unsigned *pi_channels, unsigned *pi_original_channels,
568                       unsigned *pi_bits,
569                       const uint8_t *p_header )
570 {
571     const uint8_t i_header = p_header[4];
572
573     switch( (i_header >> 4) & 0x3 )
574     {
575     case 0:
576         *pi_rate = 48000;
577         break;
578     case 1:
579         *pi_rate = 96000;
580         break;
581     case 2:
582         *pi_rate = 44100;
583         break;
584     case 3:
585         *pi_rate = 32000;
586         break;
587     }
588
589     *pi_channels = (i_header & 0x7) + 1;
590     switch( *pi_channels - 1 )
591     {
592     case 0:
593         *pi_original_channels = AOUT_CHAN_CENTER;
594         break;
595     case 1:
596         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
597         break;
598     case 2:
599         /* This is unsure. */
600         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_LFE;
601         break;
602     case 3:
603         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
604                                | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
605         break;
606     case 4:
607         /* This is unsure. */
608         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
609                                | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
610                                | AOUT_CHAN_LFE;
611         break;
612     case 5:
613         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
614                                | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
615                                | AOUT_CHAN_CENTER | AOUT_CHAN_LFE;
616         break;
617     case 6:
618         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
619                                | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
620                                | AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT
621                                | AOUT_CHAN_MIDDLERIGHT;
622         break;
623     case 7:
624         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
625                                | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
626                                | AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT
627                                | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE;
628         break;
629     }
630
631     switch( (i_header >> 6) & 0x3 )
632     {
633     case 2:
634         *pi_bits = 24;
635         break;
636     case 1:
637         *pi_bits = 20;
638         break;
639     case 0:
640     default:
641         *pi_bits = 16;
642         break;
643     }
644
645     /* Check frame sync and drop it. */
646     if( p_header[5] != 0x80 )
647         return -1;
648     return 0;
649 }
650
651 static const unsigned p_aob_group1[21][6] = {
652     { AOUT_CHAN_CENTER, 0 },
653     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 0 },
654     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 0 },
655     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 0 },
656     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 0 },
657     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 0 },
658     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 0 },
659     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 0 },
660     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 0 },
661     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 0 },
662     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 0 },
663     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 0 },
664     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 0 },
665     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,   0 },
666     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,   0 },
667     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,   0 },
668     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,   0 },
669     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,   0 },
670     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0  },
671     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0  },
672     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0  },
673 };
674 static const unsigned p_aob_group2[21][6] = {
675     { 0 },
676     { 0 },
677     { AOUT_CHAN_REARCENTER, 0 },
678     { AOUT_CHAN_REARLEFT,   AOUT_CHAN_REARRIGHT,    0 },
679     { AOUT_CHAN_LFE,        0 },
680     { AOUT_CHAN_LFE,        AOUT_CHAN_REARCENTER,   0 },
681     { AOUT_CHAN_LFE,        AOUT_CHAN_REARLEFT,     AOUT_CHAN_REARRIGHT,    0 },
682     { AOUT_CHAN_CENTER,     0 },
683     { AOUT_CHAN_CENTER,     AOUT_CHAN_REARCENTER, 0 },
684     { AOUT_CHAN_CENTER,     AOUT_CHAN_REARLEFT,   AOUT_CHAN_REARRIGHT,    0 },
685     { AOUT_CHAN_CENTER,     AOUT_CHAN_LFE,        0 },
686     { AOUT_CHAN_CENTER,     AOUT_CHAN_LFE,        AOUT_CHAN_REARCENTER,   0 },
687     { AOUT_CHAN_CENTER,     AOUT_CHAN_LFE,        AOUT_CHAN_REARLEFT,     AOUT_CHAN_REARRIGHT,    0 },
688     { AOUT_CHAN_REARCENTER, 0 },
689     { AOUT_CHAN_REARLEFT,   AOUT_CHAN_REARRIGHT,    0 },
690     { AOUT_CHAN_LFE,        0 },
691     { AOUT_CHAN_LFE,        AOUT_CHAN_REARCENTER,   0 },
692     { AOUT_CHAN_LFE,        AOUT_CHAN_REARLEFT,     AOUT_CHAN_REARRIGHT,    0 },
693     { AOUT_CHAN_LFE,        0 },
694     { AOUT_CHAN_CENTER,     0 },
695     { AOUT_CHAN_CENTER,     AOUT_CHAN_LFE,          0 },
696 };
697
698 static int AobHeader( unsigned *pi_rate,
699                       unsigned *pi_channels, unsigned *pi_layout,
700                       unsigned *pi_bits,
701                       unsigned *pi_padding,
702                       aob_group_t g[2],
703                       const uint8_t *p_header )
704 {
705     const unsigned i_header_size = GetWBE( &p_header[1] );
706     if( i_header_size + 3 < LPCM_AOB_HEADER_LEN )
707         return VLC_EGENERIC;
708
709     *pi_padding = 3+i_header_size - LPCM_AOB_HEADER_LEN;
710
711     const int i_index_size_g1 = (p_header[6] >> 4) & 0x0f;
712     const int i_index_size_g2 = (p_header[6]     ) & 0x0f;
713     const int i_index_rate_g1 = (p_header[7] >> 4) & 0x0f;
714     const int i_index_rate_g2 = (p_header[7]     ) & 0x0f;
715     const int i_assignment     = p_header[9];
716
717     /* Validate */
718     if( i_index_size_g1 > 0x02 ||
719         ( i_index_size_g2 != 0x0f && i_index_size_g2 > 0x02 ) )
720         return VLC_EGENERIC;
721     if( (i_index_rate_g1 & 0x07) > 0x02 ||
722         ( i_index_rate_g2 != 0x0f && (i_index_rate_g1 & 0x07) > 0x02 ) )
723         return VLC_EGENERIC;
724     if( i_assignment > 20 )
725         return VLC_EGENERIC;
726
727     /* */
728     *pi_bits = 16 + 4 * i_index_size_g1;
729     if( i_index_rate_g1 & 0x08 )
730         *pi_rate = 44100 << (i_index_rate_g1 & 0x07);
731     else
732         *pi_rate = 48000 << (i_index_rate_g1 & 0x07);
733
734
735     /* Group1 */
736     unsigned i_channels1 = 0;
737     unsigned i_layout1 = 0;
738     for( int i = 0; p_aob_group1[i_assignment][i] != 0; i++ )
739     {
740         i_channels1++;
741         i_layout1 |= p_aob_group1[i_assignment][i];
742     }
743     /* Group2 */
744     unsigned i_channels2 = 0;
745     unsigned i_layout2 = 0;
746     if( i_index_size_g2 != 0x0f && i_index_rate_g2 != 0x0f )
747     {
748         for( int i = 0; p_aob_group2[i_assignment][i] != 0; i++ )
749         {
750             i_channels2++;
751             i_layout2 |= p_aob_group2[i_assignment][i];
752         }
753         assert( (i_layout1 & i_layout2) == 0 );
754     }
755     /* It is enabled only when presents and compatible wih group1 */
756     const bool b_group2_used = i_index_size_g1 == i_index_size_g2 &&
757                                i_index_rate_g1 == i_index_rate_g2;
758
759     /* */
760     *pi_channels = i_channels1 + ( b_group2_used ? i_channels2 : 0 );
761     *pi_layout   = i_layout1   | ( b_group2_used ? i_layout2   : 0 );
762
763     /* */
764     for( unsigned i = 0; i < 2; i++ )
765     {
766         const unsigned *p_aob = i == 0 ? p_aob_group1[i_assignment] :
767                                          p_aob_group2[i_assignment];
768         g[i].i_channels = i == 0 ? i_channels1 :
769                                    i_channels2;
770
771         g[i].b_used = i == 0 || b_group2_used;
772         if( !g[i].b_used )
773             continue;
774         for( unsigned j = 0; j < g[i].i_channels; j++ )
775         {
776             g[i].pi_position[j] = 0;
777             for( int k = 0; pi_vlc_chan_order_wg4[k] != 0; k++ )
778             {
779                 const unsigned i_channel = pi_vlc_chan_order_wg4[k];
780                 if( i_channel == p_aob[j] )
781                     break;
782                 if( (*pi_layout) & i_channel )
783                     g[i].pi_position[j]++;
784             }
785         }
786     }
787     return VLC_SUCCESS;
788 }
789
790 static int BdHeader( unsigned *pi_rate,
791                      unsigned *pi_channels, unsigned *pi_original_channels,
792                      unsigned *pi_bits,
793                      const uint8_t *p_header )
794 {
795     const uint32_t h = GetDWBE( p_header );
796     switch( ( h & 0xf000) >> 12 )
797     {
798     case 1:
799         *pi_channels = 1;
800         *pi_original_channels = AOUT_CHAN_CENTER;
801         break;
802     case 3:
803         *pi_channels = 2;
804         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
805         break;
806     case 4:
807         *pi_channels = 3;
808         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER;
809         break;
810     case 5:
811         *pi_channels = 3;
812         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARCENTER;
813         break;
814     case 6:
815         *pi_channels = 4;
816         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
817                                 AOUT_CHAN_REARCENTER;
818         break;
819     case 7:
820         *pi_channels = 4;
821         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
822                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
823         break;
824     case 8:
825         *pi_channels = 5;
826         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
827                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
828         break;
829     case 9:
830         *pi_channels = 6;
831         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
832                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
833                                 AOUT_CHAN_LFE;
834         break;
835     case 10:
836         *pi_channels = 7;
837         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
838                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
839                                 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT;
840         break;
841     case 11:
842         *pi_channels = 8;
843         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
844                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
845                                 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
846                                 AOUT_CHAN_LFE;
847         break;
848
849     default:
850         return -1;
851     }
852     switch( (h >> 6) & 0x03 )
853     {
854     case 1:
855         *pi_bits = 16;
856         break;
857     case 2: /* 20 bits but samples are stored on 24 bits */
858     case 3: /* 24 bits */
859         *pi_bits = 24;
860         break;
861     default:
862         return -1;
863     }
864     switch( (h >> 8) & 0x0f ) 
865     {
866     case 1:
867         *pi_rate = 48000;
868         break;
869     case 4:
870         *pi_rate = 96000;
871         break;
872     case 5:
873         *pi_rate = 192000;
874         break;
875     default:
876         return -1;
877     }
878     return 0;
879 }
880
881 static void VobExtract( aout_buffer_t *p_aout_buffer, block_t *p_block,
882                         unsigned i_bits )
883 {
884     uint8_t *p_out = p_aout_buffer->p_buffer;
885
886     /* 20/24 bits LPCM use special packing */
887     if( i_bits == 24 )
888     {
889         while( p_block->i_buffer / 12 )
890         {
891             /* Sample 1 */
892             p_out[0] = p_block->p_buffer[0];
893             p_out[1] = p_block->p_buffer[1];
894             p_out[2] = p_block->p_buffer[8];
895             /* Sample 2 */
896             p_out[3] = p_block->p_buffer[2];
897             p_out[4] = p_block->p_buffer[3];
898             p_out[5] = p_block->p_buffer[9];
899             /* Sample 3 */
900             p_out[6] = p_block->p_buffer[4];
901             p_out[7] = p_block->p_buffer[5];
902             p_out[8] = p_block->p_buffer[10];
903             /* Sample 4 */
904             p_out[9] = p_block->p_buffer[6];
905             p_out[10] = p_block->p_buffer[7];
906             p_out[11] = p_block->p_buffer[11];
907
908             p_block->i_buffer -= 12;
909             p_block->p_buffer += 12;
910             p_out += 12;
911         }
912     }
913     else if( i_bits == 20 )
914     {
915         while( p_block->i_buffer / 10 )
916         {
917             /* Sample 1 */
918             p_out[0] = p_block->p_buffer[0];
919             p_out[1] = p_block->p_buffer[1];
920             p_out[2] = p_block->p_buffer[8] & 0xF0;
921             /* Sample 2 */
922             p_out[3] = p_block->p_buffer[2];
923             p_out[4] = p_block->p_buffer[3];
924             p_out[5] = p_block->p_buffer[8] << 4;
925             /* Sample 3 */
926             p_out[6] = p_block->p_buffer[4];
927             p_out[7] = p_block->p_buffer[5];
928             p_out[8] = p_block->p_buffer[9] & 0xF0;
929             /* Sample 4 */
930             p_out[9] = p_block->p_buffer[6];
931             p_out[10] = p_block->p_buffer[7];
932             p_out[11] = p_block->p_buffer[9] << 4;
933
934             p_block->i_buffer -= 10;
935             p_block->p_buffer += 10;
936             p_out += 12;
937         }
938     }
939     else
940     {
941         assert( i_bits == 16 );
942         memcpy( p_out, p_block->p_buffer, p_block->i_buffer );
943     }
944 }
945 static void AobExtract( aout_buffer_t *p_aout_buffer,
946                         block_t *p_block, unsigned i_bits, aob_group_t p_group[2] )
947 {
948     const unsigned i_channels = p_group[0].i_channels +
949                                 ( p_group[1].b_used ? p_group[1].i_channels : 0 );
950     uint8_t *p_out = p_aout_buffer->p_buffer;
951
952     while( p_block->i_buffer > 0 )
953     {
954         for( int i = 0; i < 2; i++ )
955         {
956             const aob_group_t *g = &p_group[1-i];
957             const unsigned int i_group_size = 2 * g->i_channels * i_bits / 8;
958
959             if( p_block->i_buffer < i_group_size )
960             {
961                 p_block->i_buffer = 0;
962                 break;
963             }
964             for( unsigned n = 0; n < 2; n++ )
965             {
966                 for( unsigned j = 0; j < g->i_channels && g->b_used; j++ )
967                 {
968                     const int i_src = n * g->i_channels + j;
969                     const int i_dst = n * i_channels + g->pi_position[j];
970
971                     if( i_bits == 24 )
972                     {
973                         p_out[3*i_dst+0] = p_block->p_buffer[2*i_src+0];
974                         p_out[3*i_dst+1] = p_block->p_buffer[2*i_src+1];
975                         p_out[3*i_dst+2] = p_block->p_buffer[4*g->i_channels+i_src];
976                     }
977                     else if( i_bits == 20 )
978                     {
979                         p_out[3*i_dst+0] = p_block->p_buffer[2*i_src+0];
980                         p_out[3*i_dst+1] = p_block->p_buffer[2*i_src+1];
981                         if( n == 0 )
982                             p_out[3*i_dst+2] = (p_block->p_buffer[4*g->i_channels+i_src]     ) & 0xf0;
983                         else
984                             p_out[3*i_dst+2] = (p_block->p_buffer[4*g->i_channels+i_src] << 4) & 0xf0;
985                     }
986                     else
987                     {
988                         assert( i_bits == 16 );
989                         p_out[2*i_dst+0] = p_block->p_buffer[2*i_src+0];
990                         p_out[2*i_dst+1] = p_block->p_buffer[2*i_src+1];
991                     }
992                 }
993             }
994
995             p_block->i_buffer -= i_group_size;
996             p_block->p_buffer += i_group_size;
997         }
998         /* */
999         p_out += (i_bits == 16 ? 2 : 3) * i_channels * 2;
1000
1001     }
1002 }
1003 static void BdExtract( aout_buffer_t *p_aout_buffer, block_t *p_block )
1004 {
1005     memcpy( p_aout_buffer->p_buffer, p_block->p_buffer, p_block->i_buffer );
1006 }
1007