]> git.sesse.net Git - vlc/blob - modules/codec/aes3.c
AES3: decode to native endian
[vlc] / modules / codec / aes3.c
1 /*****************************************************************************
2  * aes3.c: aes3 decoder/packetizer module
3  *****************************************************************************
4  * Copyright (C) 2008 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_codec.h>
34 #include <assert.h>
35
36 /*****************************************************************************
37  * Module descriptor
38  *****************************************************************************/
39 static int  OpenDecoder   ( vlc_object_t * );
40 static int  OpenPacketizer( vlc_object_t * );
41 static void Close         ( vlc_object_t * );
42
43 vlc_module_begin ()
44
45     set_category( CAT_INPUT )
46     set_subcategory( SUBCAT_INPUT_ACODEC )
47     set_description( N_("AES3/SMPTE 302M audio decoder") )
48     set_capability( "decoder", 100 )
49     set_callbacks( OpenDecoder, Close )
50
51     add_submodule ()
52     set_description( N_("AES3/SMPTE 302M audio packetizer") )
53     set_capability( "packetizer", 100 )
54     set_callbacks( OpenPacketizer, Close )
55
56 vlc_module_end ()
57
58 /*****************************************************************************
59  * decoder_sys_t : aes3 decoder descriptor
60  *****************************************************************************/
61 struct decoder_sys_t
62 {
63     /*
64      * Output properties
65      */
66     date_t end_date;
67 };
68
69 #define AES3_HEADER_LEN 4
70
71 /*****************************************************************************
72  * Local prototypes
73  *****************************************************************************/
74 static int Open( decoder_t *p_dec, bool b_packetizer );
75
76 static block_t *Parse( decoder_t *p_dec, int *pi_frame_length, int *pi_bits,
77                        block_t **pp_block, bool b_packetizer );
78
79 /*****************************************************************************
80  * OpenDecoder:
81  *****************************************************************************/
82 static int OpenDecoder( vlc_object_t *p_this )
83 {
84     decoder_t *p_dec = (decoder_t*)p_this;
85
86     return Open( p_dec, false );
87 }
88
89 /*****************************************************************************
90  * OpenPacketizer:
91  *****************************************************************************/
92 static int OpenPacketizer( vlc_object_t *p_this )
93 {
94     decoder_t *p_dec = (decoder_t*)p_this;
95
96     return Open( p_dec, true );
97 }
98
99 /*****************************************************************************
100  * Close : aes3 decoder destruction
101  *****************************************************************************/
102 static void Close( vlc_object_t *p_this )
103 {
104     decoder_t *p_dec = (decoder_t*)p_this;
105     free( p_dec->p_sys );
106 }
107
108 static const uint8_t reverse[256] = {
109     0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0,
110     0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
111     0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4,
112     0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
113     0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc,
114     0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
115     0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca,
116     0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
117     0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6,
118     0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
119     0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1,
120     0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
121     0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9,
122     0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
123     0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd,
124     0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
125     0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3,
126     0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
127     0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7,
128     0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
129     0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf,
130     0x3f, 0xbf, 0x7f, 0xff
131 };
132
133 /*****************************************************************************
134  * Decode: decodes an aes3 frame.
135  ****************************************************************************
136  * Beware, this function must be fed with complete frames (PES packet).
137  *****************************************************************************/
138 static block_t *Decode( decoder_t *p_dec, block_t **pp_block )
139 {
140     decoder_sys_t *p_sys = p_dec->p_sys;
141     block_t       *p_block;
142     block_t       *p_aout_buffer;
143     int            i_frame_length, i_bits;
144
145     p_block = Parse( p_dec, &i_frame_length, &i_bits, pp_block, false );
146     if( !p_block )
147         return NULL;
148
149     p_aout_buffer = decoder_NewAudioBuffer( p_dec, i_frame_length );
150     if( p_aout_buffer == NULL )
151         goto exit;
152
153     p_aout_buffer->i_pts = date_Get( &p_sys->end_date );
154     p_aout_buffer->i_length = date_Increment( &p_sys->end_date,
155                                       i_frame_length ) - p_aout_buffer->i_pts;
156
157     p_block->i_buffer -= AES3_HEADER_LEN;
158     p_block->p_buffer += AES3_HEADER_LEN;
159
160 #ifdef WORDS_BIGENGIAN
161 # define LOB 2
162 # define HIB 0
163 #else
164 # define LOB 0
165 # define HIB 2
166 #endif
167 #define  MIB 1
168     if( i_bits == 24 )
169     {
170         uint8_t *p_out = p_aout_buffer->p_buffer;
171
172         while( p_block->i_buffer / 7 )
173         {
174             p_out[LOB] = reverse[p_block->p_buffer[0]];
175             p_out[MIB] = reverse[p_block->p_buffer[1]];
176             p_out[HIB] = reverse[p_block->p_buffer[2]];
177             p_out += 3;
178
179             p_out[LOB] =  (reverse[p_block->p_buffer[3]] >> 4)
180                        | ((reverse[p_block->p_buffer[4]] << 4) & 0xf0);
181             p_out[MIB] =  (reverse[p_block->p_buffer[4]] >> 4)
182                        | ((reverse[p_block->p_buffer[5]] << 4) & 0xf0);
183             p_out[HIB] =  (reverse[p_block->p_buffer[5]] >> 4)
184                        | ((reverse[p_block->p_buffer[6]] << 4) & 0xf0);
185             p_out += 3;
186
187             p_block->i_buffer -= 7;
188             p_block->p_buffer += 7;
189         }
190
191     }
192     else if( i_bits == 20 )
193     {
194         uint8_t *p_out = p_aout_buffer->p_buffer;
195
196         while( p_block->i_buffer / 6 )
197         {
198             p_out[LOB] = ((reverse[p_block->p_buffer[0]] << 4) & 0xf0);
199             p_out[MIB] =  (reverse[p_block->p_buffer[0]] >> 4)
200                        | ((reverse[p_block->p_buffer[1]] << 4) & 0xf0);
201             p_out[HIB] =  (reverse[p_block->p_buffer[1]] >> 4)
202                        | ((reverse[p_block->p_buffer[2]] << 4) & 0xf0);
203             p_out += 3;
204
205             p_out[LOB] = ((reverse[p_block->p_buffer[3]] << 4) & 0xf0);
206             p_out[MIB] =  (reverse[p_block->p_buffer[3]] >> 4)
207                        | ((reverse[p_block->p_buffer[4]] << 4) & 0xf0);
208             p_out[HIB] =  (reverse[p_block->p_buffer[4]] >> 4)
209                        | ((reverse[p_block->p_buffer[5]] << 4) & 0xf0);
210             p_out += 3;
211
212             p_block->i_buffer -= 6;
213             p_block->p_buffer += 6;
214         }
215     }
216 #undef  HIB
217 #define HIB (!(LOB))
218     else
219     {
220         uint8_t *p_out = p_aout_buffer->p_buffer;
221
222         assert( i_bits == 16 );
223
224         while( p_block->i_buffer / 5 )
225         {
226             p_out[LOB] = reverse[p_block->p_buffer[0]];
227             p_out[HIB] = reverse[p_block->p_buffer[1]];
228             p_out += 2;
229
230             p_out[LOB] =  (reverse[p_block->p_buffer[2]] >> 4)
231                        | ((reverse[p_block->p_buffer[3]] << 4) & 0xf0);
232             p_out[HIB] =  (reverse[p_block->p_buffer[3]] >> 4)
233                        | ((reverse[p_block->p_buffer[4]] << 4) & 0xf0);
234             p_out += 2;
235
236             p_block->i_buffer -= 5;
237             p_block->p_buffer += 5;
238         }
239     }
240
241 exit:
242     block_Release( p_block );
243     return p_aout_buffer;
244 }
245
246 /*****************************************************************************
247  * Packetize: packetizes an aes3 frame.
248  ****************************************************************************
249  * Beware, this function must be fed with complete frames (PES packet).
250  *****************************************************************************/
251 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
252 {
253     decoder_sys_t *p_sys = p_dec->p_sys;
254     block_t       *p_block;
255     int           i_frame_length, i_bits;
256
257     p_block = Parse( p_dec, &i_frame_length, &i_bits, pp_block, true );
258     if( !p_block )
259         return NULL;
260
261     p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date );
262     p_block->i_length = date_Increment( &p_sys->end_date, i_frame_length ) - p_block->i_pts;
263
264     /* Just pass on the incoming frame */
265     return p_block;
266 }
267
268 /*****************************************************************************
269  *
270  ****************************************************************************/
271 static int Open( decoder_t *p_dec, bool b_packetizer )
272 {
273     decoder_sys_t *p_sys;
274
275     if( p_dec->fmt_in.i_codec != VLC_CODEC_302M )
276         return VLC_EGENERIC;
277
278     /* Allocate the memory needed to store the decoder's structure */
279     p_dec->p_sys = p_sys = malloc( sizeof(decoder_sys_t) );
280
281     if( unlikely( !p_sys ) )
282         return VLC_EGENERIC;
283
284     /* Misc init */
285     date_Init( &p_sys->end_date, 48000, 1 );
286     date_Set( &p_sys->end_date, 0 );
287
288     /* Set output properties */
289     p_dec->fmt_out.i_cat = AUDIO_ES;
290     p_dec->fmt_out.audio.i_rate = 48000;
291
292     /* Set callback */
293     if( b_packetizer )
294     {
295         p_dec->fmt_out.i_codec = VLC_CODEC_302M;
296
297         p_dec->pf_decode_audio = NULL;
298         p_dec->pf_packetize    = Packetize;
299     }
300     else
301     {
302         p_dec->fmt_out.i_codec = VLC_CODEC_S16N;
303         p_dec->fmt_out.audio.i_bitspersample = 16;
304
305         p_dec->pf_decode_audio = Decode;
306         p_dec->pf_packetize    = NULL;
307     }
308     return VLC_SUCCESS;
309 }
310
311 static const unsigned int pi_original_channels[4] = {
312     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
313     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
314         AOUT_CHAN_CENTER | AOUT_CHAN_LFE,
315     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
316         AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
317         AOUT_CHAN_CENTER | AOUT_CHAN_LFE,
318     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
319         AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
320         AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
321         AOUT_CHAN_CENTER | AOUT_CHAN_LFE,
322 };
323
324 static block_t *Parse( decoder_t *p_dec, int *pi_frame_length, int *pi_bits,
325                        block_t **pp_block, bool b_packetizer )
326 {
327     decoder_sys_t *p_sys = p_dec->p_sys;
328     block_t       *p_block;
329     uint32_t h;
330     unsigned int i_size;
331     int i_channels;
332     int i_bits;
333
334     if( !pp_block || !*pp_block ) return NULL;
335
336     p_block = *pp_block;
337     *pp_block = NULL; /* So the packet doesn't get re-sent */
338
339     /* Date management */
340     if( p_block->i_pts > VLC_TS_INVALID &&
341         p_block->i_pts != date_Get( &p_sys->end_date ) )
342     {
343         date_Set( &p_sys->end_date, p_block->i_pts );
344     }
345
346     if( !date_Get( &p_sys->end_date ) )
347     {
348         /* We've just started the stream, wait for the first PTS. */
349         block_Release( p_block );
350         return NULL;
351     }
352
353     if( p_block->i_buffer <= AES3_HEADER_LEN )
354     {
355         msg_Err(p_dec, "frame is too short");
356         block_Release( p_block );
357         return NULL;
358     }
359
360     /*
361      * AES3 header :
362      * size:            16
363      * number channels   2
364      * channel_id        8
365      * bits per samples  2
366      * alignments        4
367      */
368
369     h = GetDWBE( p_block->p_buffer );
370     i_size = (h >> 16) & 0xffff;
371     i_channels = 2 + 2*( (h >> 14) & 0x03 );
372     i_bits = 16 + 4*( (h >> 4)&0x03 );
373
374     if( AES3_HEADER_LEN + i_size != p_block->i_buffer || i_bits > 24 )
375     {
376         msg_Err(p_dec, "frame has invalid header");
377         block_Release( p_block );
378         return NULL;
379     }
380
381     /* Set output properties */
382     if( b_packetizer )
383     {
384         p_dec->fmt_out.audio.i_bitspersample = i_bits;
385     }
386     else
387     {
388         p_dec->fmt_out.i_codec = i_bits == 16 ? VLC_CODEC_S16N
389                                               : VLC_CODEC_S24N;
390         p_dec->fmt_out.audio.i_bitspersample = i_bits == 16 ? 16 : 24;
391     }
392
393     p_dec->fmt_out.audio.i_channels = i_channels;
394     p_dec->fmt_out.audio.i_original_channels = pi_original_channels[i_channels/2-1];
395     p_dec->fmt_out.audio.i_physical_channels = pi_original_channels[i_channels/2-1];
396
397     *pi_frame_length = (p_block->i_buffer - AES3_HEADER_LEN) / ( (4+i_bits) * i_channels / 8 );
398     *pi_bits = i_bits;
399     return p_block;
400 }
401