]> git.sesse.net Git - vlc/blob - modules/codec/aes3.c
upnp: change item b_net and i_type
[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     if( i_bits == 24 )
161     {
162         uint32_t *p_out = (uint32_t *)p_aout_buffer->p_buffer;
163
164         while( p_block->i_buffer / 7 )
165         {
166             *(p_out++) =  (reverse[p_block->p_buffer[0]] <<  8)
167                         | (reverse[p_block->p_buffer[1]] << 16)
168                         | (reverse[p_block->p_buffer[2]] << 24);
169             *(p_out++) = ((reverse[p_block->p_buffer[3]] <<  4)
170                         | (reverse[p_block->p_buffer[4]] << 12)
171                         | (reverse[p_block->p_buffer[5]] << 20)
172                         | (reverse[p_block->p_buffer[6]] << 28)) & 0xFFFFFF00;
173
174             p_block->i_buffer -= 7;
175             p_block->p_buffer += 7;
176         }
177
178     }
179     else if( i_bits == 20 )
180     {
181         uint32_t *p_out = (uint32_t *)p_aout_buffer->p_buffer;
182
183         while( p_block->i_buffer / 6 )
184         {
185             *(p_out++) = (reverse[p_block->p_buffer[0]] << 12)
186                        | (reverse[p_block->p_buffer[1]] << 20)
187                        | (reverse[p_block->p_buffer[2]] << 28);
188             *(p_out++) = (reverse[p_block->p_buffer[3]] << 12)
189                        | (reverse[p_block->p_buffer[4]] << 20)
190                        | (reverse[p_block->p_buffer[5]] << 28);
191
192             p_block->i_buffer -= 6;
193             p_block->p_buffer += 6;
194         }
195     }
196     else
197     {
198         uint16_t *p_out = (uint16_t *)p_aout_buffer->p_buffer;
199
200         assert( i_bits == 16 );
201
202         while( p_block->i_buffer / 5 )
203         {
204             *(p_out++) =  reverse[p_block->p_buffer[0]]
205                         | reverse[p_block->p_buffer[1]];
206             *(p_out++) = (reverse[p_block->p_buffer[2]] >>  4)
207                        | (reverse[p_block->p_buffer[3]] <<  4)
208                        | (reverse[p_block->p_buffer[4]] << 12);
209
210             p_block->i_buffer -= 5;
211             p_block->p_buffer += 5;
212         }
213     }
214
215 exit:
216     block_Release( p_block );
217     return p_aout_buffer;
218 }
219
220 /*****************************************************************************
221  * Packetize: packetizes an aes3 frame.
222  ****************************************************************************
223  * Beware, this function must be fed with complete frames (PES packet).
224  *****************************************************************************/
225 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
226 {
227     decoder_sys_t *p_sys = p_dec->p_sys;
228     block_t       *p_block;
229     int           i_frame_length, i_bits;
230
231     p_block = Parse( p_dec, &i_frame_length, &i_bits, pp_block, true );
232     if( !p_block )
233         return NULL;
234
235     p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date );
236     p_block->i_length = date_Increment( &p_sys->end_date, i_frame_length ) - p_block->i_pts;
237
238     /* Just pass on the incoming frame */
239     return p_block;
240 }
241
242 /*****************************************************************************
243  *
244  ****************************************************************************/
245 static int Open( decoder_t *p_dec, bool b_packetizer )
246 {
247     decoder_sys_t *p_sys;
248
249     if( p_dec->fmt_in.i_codec != VLC_CODEC_302M )
250         return VLC_EGENERIC;
251
252     /* Allocate the memory needed to store the decoder's structure */
253     p_dec->p_sys = p_sys = malloc( sizeof(decoder_sys_t) );
254
255     if( unlikely( !p_sys ) )
256         return VLC_EGENERIC;
257
258     /* Misc init */
259     date_Init( &p_sys->end_date, 48000, 1 );
260     date_Set( &p_sys->end_date, 0 );
261
262     /* Set output properties */
263     p_dec->fmt_out.i_cat = AUDIO_ES;
264     p_dec->fmt_out.audio.i_rate = 48000;
265
266     /* Set callback */
267     if( b_packetizer )
268     {
269         p_dec->fmt_out.i_codec = VLC_CODEC_302M;
270
271         p_dec->pf_decode_audio = NULL;
272         p_dec->pf_packetize    = Packetize;
273     }
274     else
275     {
276         p_dec->fmt_out.i_codec = VLC_CODEC_S16N;
277         p_dec->fmt_out.audio.i_bitspersample = 16;
278
279         p_dec->pf_decode_audio = Decode;
280         p_dec->pf_packetize    = NULL;
281     }
282     return VLC_SUCCESS;
283 }
284
285 static const unsigned int pi_original_channels[4] = {
286     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
287     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
288         AOUT_CHAN_CENTER | AOUT_CHAN_LFE,
289     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
290         AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
291         AOUT_CHAN_CENTER | AOUT_CHAN_LFE,
292     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
293         AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
294         AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
295         AOUT_CHAN_CENTER | AOUT_CHAN_LFE,
296 };
297
298 static block_t *Parse( decoder_t *p_dec, int *pi_frame_length, int *pi_bits,
299                        block_t **pp_block, bool b_packetizer )
300 {
301     decoder_sys_t *p_sys = p_dec->p_sys;
302     block_t       *p_block;
303     uint32_t h;
304     unsigned int i_size;
305     int i_channels;
306     int i_bits;
307
308     if( !pp_block || !*pp_block ) return NULL;
309
310     p_block = *pp_block;
311     *pp_block = NULL; /* So the packet doesn't get re-sent */
312
313     /* Date management */
314     if( p_block->i_pts > VLC_TS_INVALID &&
315         p_block->i_pts != date_Get( &p_sys->end_date ) )
316     {
317         date_Set( &p_sys->end_date, p_block->i_pts );
318     }
319
320     if( !date_Get( &p_sys->end_date ) )
321     {
322         /* We've just started the stream, wait for the first PTS. */
323         block_Release( p_block );
324         return NULL;
325     }
326
327     if( p_block->i_buffer <= AES3_HEADER_LEN )
328     {
329         msg_Err(p_dec, "frame is too short");
330         block_Release( p_block );
331         return NULL;
332     }
333
334     /*
335      * AES3 header :
336      * size:            16
337      * number channels   2
338      * channel_id        8
339      * bits per samples  2
340      * alignments        4
341      */
342
343     h = GetDWBE( p_block->p_buffer );
344     i_size = (h >> 16) & 0xffff;
345     i_channels = 2 + 2*( (h >> 14) & 0x03 );
346     i_bits = 16 + 4*( (h >> 4)&0x03 );
347
348     if( AES3_HEADER_LEN + i_size != p_block->i_buffer || i_bits > 24 )
349     {
350         msg_Err(p_dec, "frame has invalid header");
351         block_Release( p_block );
352         return NULL;
353     }
354
355     /* Set output properties */
356     if( b_packetizer )
357     {
358         p_dec->fmt_out.audio.i_bitspersample = i_bits;
359     }
360     else
361     {
362         p_dec->fmt_out.i_codec = i_bits == 16 ? VLC_CODEC_S16N : VLC_CODEC_S32N;
363         p_dec->fmt_out.audio.i_bitspersample = i_bits == 16 ? 16 : 32;
364     }
365
366     p_dec->fmt_out.audio.i_channels = i_channels;
367     p_dec->fmt_out.audio.i_original_channels = pi_original_channels[i_channels/2-1];
368     p_dec->fmt_out.audio.i_physical_channels = pi_original_channels[i_channels/2-1];
369
370     *pi_frame_length = (p_block->i_buffer - AES3_HEADER_LEN) / ( (4+i_bits) * i_channels / 8 );
371     *pi_bits = i_bits;
372     return p_block;
373 }
374