]> git.sesse.net Git - vlc/blob - modules/codec/lpcm.c
Start a DVD 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_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     p_block = block_New( p_enc, i_num_frames * i_frame_size );
499     if( !p_block )
500         return NULL;
501
502     uint8_t i_freq_code = 0;
503
504     switch( p_sys->i_rate ) {
505     case 48000:
506         i_freq_code = 0;
507         break;
508     case 96000:
509         i_freq_code = 1;
510         break;
511     case 44100:
512         i_freq_code = 2;
513         break;
514     case 32000:
515         i_freq_code = 3;
516         break;
517     }
518
519     int i_bytes_consumed = 0;
520
521     for ( int i = 0; i < i_num_frames; ++i )
522     {
523         uint8_t *frame = (uint8_t *)p_block->p_buffer + i * i_frame_size;
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     memcpy( p_sys->p_buffer,
544             p_aout_buf->p_buffer + i_bytes_consumed,
545             i_leftover_samples * p_sys->i_channels * 2 );
546     p_sys->i_buffer_used = i_leftover_samples;
547
548     /* 
549      * The pts is strictly not correct if we have samples kept from
550      * a previous buffer, but the frames are so small it should be OK.
551      */
552     p_block->i_dts = p_block->i_pts = p_aout_buf->i_pts;
553     p_block->i_length = (int64_t)i_num_frames * p_sys->i_frame_samples * CLOCK_FREQ / p_sys->i_rate;
554
555     return p_block;
556 }
557
558 /*****************************************************************************
559  *
560  *****************************************************************************/
561 static int VobHeader( unsigned *pi_rate,
562                       unsigned *pi_channels, unsigned *pi_original_channels,
563                       unsigned *pi_bits,
564                       const uint8_t *p_header )
565 {
566     const uint8_t i_header = p_header[4];
567
568     switch( (i_header >> 4) & 0x3 )
569     {
570     case 0:
571         *pi_rate = 48000;
572         break;
573     case 1:
574         *pi_rate = 96000;
575         break;
576     case 2:
577         *pi_rate = 44100;
578         break;
579     case 3:
580         *pi_rate = 32000;
581         break;
582     }
583
584     *pi_channels = (i_header & 0x7) + 1;
585     switch( *pi_channels - 1 )
586     {
587     case 0:
588         *pi_original_channels = AOUT_CHAN_CENTER;
589         break;
590     case 1:
591         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
592         break;
593     case 2:
594         /* This is unsure. */
595         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_LFE;
596         break;
597     case 3:
598         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
599                                | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
600         break;
601     case 4:
602         /* This is unsure. */
603         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
604                                | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
605                                | AOUT_CHAN_LFE;
606         break;
607     case 5:
608         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
609                                | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
610                                | AOUT_CHAN_CENTER | AOUT_CHAN_LFE;
611         break;
612     case 6:
613         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
614                                | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
615                                | AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT
616                                | AOUT_CHAN_MIDDLERIGHT;
617         break;
618     case 7:
619         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
620                                | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
621                                | AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT
622                                | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE;
623         break;
624     }
625
626     switch( (i_header >> 6) & 0x3 )
627     {
628     case 2:
629         *pi_bits = 24;
630         break;
631     case 1:
632         *pi_bits = 20;
633         break;
634     case 0:
635     default:
636         *pi_bits = 16;
637         break;
638     }
639
640     /* Check frame sync and drop it. */
641     if( p_header[5] != 0x80 )
642         return -1;
643     return 0;
644 }
645
646 static const unsigned p_aob_group1[21][6] = {
647     { AOUT_CHAN_CENTER, 0 },
648     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 0 },
649     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 0 },
650     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 0 },
651     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 0 },
652     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, 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, AOUT_CHAN_CENTER,   0 },
661     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,   0 },
662     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,   0 },
663     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,   0 },
664     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,   0 },
665     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0  },
666     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0  },
667     { AOUT_CHAN_LEFT,   AOUT_CHAN_RIGHT, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0  },
668 };
669 static const unsigned p_aob_group2[21][6] = {
670     { 0 },
671     { 0 },
672     { AOUT_CHAN_REARCENTER, 0 },
673     { AOUT_CHAN_REARLEFT,   AOUT_CHAN_REARRIGHT,    0 },
674     { AOUT_CHAN_LFE,        0 },
675     { AOUT_CHAN_LFE,        AOUT_CHAN_REARCENTER,   0 },
676     { AOUT_CHAN_LFE,        AOUT_CHAN_REARLEFT,     AOUT_CHAN_REARRIGHT,    0 },
677     { AOUT_CHAN_CENTER,     0 },
678     { AOUT_CHAN_CENTER,     AOUT_CHAN_REARCENTER, 0 },
679     { AOUT_CHAN_CENTER,     AOUT_CHAN_REARLEFT,   AOUT_CHAN_REARRIGHT,    0 },
680     { AOUT_CHAN_CENTER,     AOUT_CHAN_LFE,        0 },
681     { AOUT_CHAN_CENTER,     AOUT_CHAN_LFE,        AOUT_CHAN_REARCENTER,   0 },
682     { AOUT_CHAN_CENTER,     AOUT_CHAN_LFE,        AOUT_CHAN_REARLEFT,     AOUT_CHAN_REARRIGHT,    0 },
683     { AOUT_CHAN_REARCENTER, 0 },
684     { AOUT_CHAN_REARLEFT,   AOUT_CHAN_REARRIGHT,    0 },
685     { AOUT_CHAN_LFE,        0 },
686     { AOUT_CHAN_LFE,        AOUT_CHAN_REARCENTER,   0 },
687     { AOUT_CHAN_LFE,        AOUT_CHAN_REARLEFT,     AOUT_CHAN_REARRIGHT,    0 },
688     { AOUT_CHAN_LFE,        0 },
689     { AOUT_CHAN_CENTER,     0 },
690     { AOUT_CHAN_CENTER,     AOUT_CHAN_LFE,          0 },
691 };
692
693 static int AobHeader( unsigned *pi_rate,
694                       unsigned *pi_channels, unsigned *pi_layout,
695                       unsigned *pi_bits,
696                       unsigned *pi_padding,
697                       aob_group_t g[2],
698                       const uint8_t *p_header )
699 {
700     const unsigned i_header_size = GetWBE( &p_header[1] );
701     if( i_header_size + 3 < LPCM_AOB_HEADER_LEN )
702         return VLC_EGENERIC;
703
704     *pi_padding = 3+i_header_size - LPCM_AOB_HEADER_LEN;
705
706     const int i_index_size_g1 = (p_header[6] >> 4) & 0x0f;
707     const int i_index_size_g2 = (p_header[6]     ) & 0x0f;
708     const int i_index_rate_g1 = (p_header[7] >> 4) & 0x0f;
709     const int i_index_rate_g2 = (p_header[7]     ) & 0x0f;
710     const int i_assignment     = p_header[9];
711
712     /* Validate */
713     if( i_index_size_g1 > 0x02 ||
714         ( i_index_size_g2 != 0x0f && i_index_size_g2 > 0x02 ) )
715         return VLC_EGENERIC;
716     if( (i_index_rate_g1 & 0x07) > 0x02 ||
717         ( i_index_rate_g2 != 0x0f && (i_index_rate_g1 & 0x07) > 0x02 ) )
718         return VLC_EGENERIC;
719     if( i_assignment > 20 )
720         return VLC_EGENERIC;
721
722     /* */
723     *pi_bits = 16 + 4 * i_index_size_g1;
724     if( i_index_rate_g1 & 0x08 )
725         *pi_rate = 44100 << (i_index_rate_g1 & 0x07);
726     else
727         *pi_rate = 48000 << (i_index_rate_g1 & 0x07);
728
729
730     /* Group1 */
731     unsigned i_channels1 = 0;
732     unsigned i_layout1 = 0;
733     for( int i = 0; p_aob_group1[i_assignment][i] != 0; i++ )
734     {
735         i_channels1++;
736         i_layout1 |= p_aob_group1[i_assignment][i];
737     }
738     /* Group2 */
739     unsigned i_channels2 = 0;
740     unsigned i_layout2 = 0;
741     if( i_index_size_g2 != 0x0f && i_index_rate_g2 != 0x0f )
742     {
743         for( int i = 0; p_aob_group2[i_assignment][i] != 0; i++ )
744         {
745             i_channels2++;
746             i_layout2 |= p_aob_group2[i_assignment][i];
747         }
748         assert( (i_layout1 & i_layout2) == 0 );
749     }
750     /* It is enabled only when presents and compatible wih group1 */
751     const bool b_group2_used = i_index_size_g1 == i_index_size_g2 &&
752                                i_index_rate_g1 == i_index_rate_g2;
753
754     /* */
755     *pi_channels = i_channels1 + ( b_group2_used ? i_channels2 : 0 );
756     *pi_layout   = i_layout1   | ( b_group2_used ? i_layout2   : 0 );
757
758     /* */
759     for( unsigned i = 0; i < 2; i++ )
760     {
761         const unsigned *p_aob = i == 0 ? p_aob_group1[i_assignment] :
762                                          p_aob_group2[i_assignment];
763         g[i].i_channels = i == 0 ? i_channels1 :
764                                    i_channels2;
765
766         g[i].b_used = i == 0 || b_group2_used;
767         if( !g[i].b_used )
768             continue;
769         for( unsigned j = 0; j < g[i].i_channels; j++ )
770         {
771             g[i].pi_position[j] = 0;
772             for( int k = 0; pi_vlc_chan_order_wg4[k] != 0; k++ )
773             {
774                 const unsigned i_channel = pi_vlc_chan_order_wg4[k];
775                 if( i_channel == p_aob[j] )
776                     break;
777                 if( (*pi_layout) & i_channel )
778                     g[i].pi_position[j]++;
779             }
780         }
781     }
782     return VLC_SUCCESS;
783 }
784
785 static int BdHeader( unsigned *pi_rate,
786                      unsigned *pi_channels, unsigned *pi_original_channels,
787                      unsigned *pi_bits,
788                      const uint8_t *p_header )
789 {
790     const uint32_t h = GetDWBE( p_header );
791     switch( ( h & 0xf000) >> 12 )
792     {
793     case 1:
794         *pi_channels = 1;
795         *pi_original_channels = AOUT_CHAN_CENTER;
796         break;
797     case 3:
798         *pi_channels = 2;
799         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
800         break;
801     case 4:
802         *pi_channels = 3;
803         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER;
804         break;
805     case 5:
806         *pi_channels = 3;
807         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARCENTER;
808         break;
809     case 6:
810         *pi_channels = 4;
811         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
812                                 AOUT_CHAN_REARCENTER;
813         break;
814     case 7:
815         *pi_channels = 4;
816         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
817                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
818         break;
819     case 8:
820         *pi_channels = 5;
821         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
822                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
823         break;
824     case 9:
825         *pi_channels = 6;
826         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
827                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
828                                 AOUT_CHAN_LFE;
829         break;
830     case 10:
831         *pi_channels = 7;
832         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
833                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
834                                 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT;
835         break;
836     case 11:
837         *pi_channels = 8;
838         *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
839                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
840                                 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
841                                 AOUT_CHAN_LFE;
842         break;
843
844     default:
845         return -1;
846     }
847     switch( (h >> 6) & 0x03 )
848     {
849     case 1:
850         *pi_bits = 16;
851         break;
852     case 2: /* 20 bits but samples are stored on 24 bits */
853     case 3: /* 24 bits */
854         *pi_bits = 24;
855         break;
856     default:
857         return -1;
858     }
859     switch( (h >> 8) & 0x0f ) 
860     {
861     case 1:
862         *pi_rate = 48000;
863         break;
864     case 4:
865         *pi_rate = 96000;
866         break;
867     case 5:
868         *pi_rate = 192000;
869         break;
870     default:
871         return -1;
872     }
873     return 0;
874 }
875
876 static void VobExtract( aout_buffer_t *p_aout_buffer, block_t *p_block,
877                         unsigned i_bits )
878 {
879     uint8_t *p_out = p_aout_buffer->p_buffer;
880
881     /* 20/24 bits LPCM use special packing */
882     if( i_bits == 24 )
883     {
884         while( p_block->i_buffer / 12 )
885         {
886             /* Sample 1 */
887             p_out[0] = p_block->p_buffer[0];
888             p_out[1] = p_block->p_buffer[1];
889             p_out[2] = p_block->p_buffer[8];
890             /* Sample 2 */
891             p_out[3] = p_block->p_buffer[2];
892             p_out[4] = p_block->p_buffer[3];
893             p_out[5] = p_block->p_buffer[9];
894             /* Sample 3 */
895             p_out[6] = p_block->p_buffer[4];
896             p_out[7] = p_block->p_buffer[5];
897             p_out[8] = p_block->p_buffer[10];
898             /* Sample 4 */
899             p_out[9] = p_block->p_buffer[6];
900             p_out[10] = p_block->p_buffer[7];
901             p_out[11] = p_block->p_buffer[11];
902
903             p_block->i_buffer -= 12;
904             p_block->p_buffer += 12;
905             p_out += 12;
906         }
907     }
908     else if( i_bits == 20 )
909     {
910         while( p_block->i_buffer / 10 )
911         {
912             /* Sample 1 */
913             p_out[0] = p_block->p_buffer[0];
914             p_out[1] = p_block->p_buffer[1];
915             p_out[2] = p_block->p_buffer[8] & 0xF0;
916             /* Sample 2 */
917             p_out[3] = p_block->p_buffer[2];
918             p_out[4] = p_block->p_buffer[3];
919             p_out[5] = p_block->p_buffer[8] << 4;
920             /* Sample 3 */
921             p_out[6] = p_block->p_buffer[4];
922             p_out[7] = p_block->p_buffer[5];
923             p_out[8] = p_block->p_buffer[9] & 0xF0;
924             /* Sample 4 */
925             p_out[9] = p_block->p_buffer[6];
926             p_out[10] = p_block->p_buffer[7];
927             p_out[11] = p_block->p_buffer[9] << 4;
928
929             p_block->i_buffer -= 10;
930             p_block->p_buffer += 10;
931             p_out += 12;
932         }
933     }
934     else
935     {
936         assert( i_bits == 16 );
937         memcpy( p_out, p_block->p_buffer, p_block->i_buffer );
938     }
939 }
940 static void AobExtract( aout_buffer_t *p_aout_buffer,
941                         block_t *p_block, unsigned i_bits, aob_group_t p_group[2] )
942 {
943     const unsigned i_channels = p_group[0].i_channels +
944                                 ( p_group[1].b_used ? p_group[1].i_channels : 0 );
945     uint8_t *p_out = p_aout_buffer->p_buffer;
946
947     while( p_block->i_buffer > 0 )
948     {
949         for( int i = 0; i < 2; i++ )
950         {
951             const aob_group_t *g = &p_group[1-i];
952             const unsigned int i_group_size = 2 * g->i_channels * i_bits / 8;
953
954             if( p_block->i_buffer < i_group_size )
955             {
956                 p_block->i_buffer = 0;
957                 break;
958             }
959             for( unsigned n = 0; n < 2; n++ )
960             {
961                 for( unsigned j = 0; j < g->i_channels && g->b_used; j++ )
962                 {
963                     const int i_src = n * g->i_channels + j;
964                     const int i_dst = n * i_channels + g->pi_position[j];
965
966                     if( i_bits == 24 )
967                     {
968                         p_out[3*i_dst+0] = p_block->p_buffer[2*i_src+0];
969                         p_out[3*i_dst+1] = p_block->p_buffer[2*i_src+1];
970                         p_out[3*i_dst+2] = p_block->p_buffer[4*g->i_channels+i_src];
971                     }
972                     else if( i_bits == 20 )
973                     {
974                         p_out[3*i_dst+0] = p_block->p_buffer[2*i_src+0];
975                         p_out[3*i_dst+1] = p_block->p_buffer[2*i_src+1];
976                         if( n == 0 )
977                             p_out[3*i_dst+2] = (p_block->p_buffer[4*g->i_channels+i_src]     ) & 0xf0;
978                         else
979                             p_out[3*i_dst+2] = (p_block->p_buffer[4*g->i_channels+i_src] << 4) & 0xf0;
980                     }
981                     else
982                     {
983                         assert( i_bits == 16 );
984                         p_out[2*i_dst+0] = p_block->p_buffer[2*i_src+0];
985                         p_out[2*i_dst+1] = p_block->p_buffer[2*i_src+1];
986                     }
987                 }
988             }
989
990             p_block->i_buffer -= i_group_size;
991             p_block->p_buffer += i_group_size;
992         }
993         /* */
994         p_out += (i_bits == 16 ? 2 : 3) * i_channels * 2;
995
996     }
997 }
998 static void BdExtract( aout_buffer_t *p_aout_buffer, block_t *p_block )
999 {
1000     memcpy( p_aout_buffer->p_buffer, p_block->p_buffer, p_block->i_buffer );
1001 }
1002