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