1 /*****************************************************************************
2 * aes3.c: aes3 decoder/packetizer module
3 *****************************************************************************
4 * Copyright (C) 2008 VLC authors and VideoLAN
7 * Authors: Laurent Aimar <fenrir@videolan.org>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_codec.h>
36 /*****************************************************************************
38 *****************************************************************************/
39 static int OpenDecoder ( vlc_object_t * );
40 static int OpenPacketizer( vlc_object_t * );
41 static void Close ( vlc_object_t * );
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 )
52 set_description( N_("AES3/SMPTE 302M audio packetizer") )
53 set_capability( "packetizer", 100 )
54 set_callbacks( OpenPacketizer, Close )
58 /*****************************************************************************
59 * decoder_sys_t : aes3 decoder descriptor
60 *****************************************************************************/
69 #define AES3_HEADER_LEN 4
71 /*****************************************************************************
73 *****************************************************************************/
74 static int Open( decoder_t *p_dec, bool b_packetizer );
76 static block_t *Parse( decoder_t *p_dec, int *pi_frame_length, int *pi_bits,
77 block_t **pp_block, bool b_packetizer );
79 /*****************************************************************************
81 *****************************************************************************/
82 static int OpenDecoder( vlc_object_t *p_this )
84 decoder_t *p_dec = (decoder_t*)p_this;
86 return Open( p_dec, false );
89 /*****************************************************************************
91 *****************************************************************************/
92 static int OpenPacketizer( vlc_object_t *p_this )
94 decoder_t *p_dec = (decoder_t*)p_this;
96 return Open( p_dec, true );
99 /*****************************************************************************
100 * Close : aes3 decoder destruction
101 *****************************************************************************/
102 static void Close( vlc_object_t *p_this )
104 decoder_t *p_dec = (decoder_t*)p_this;
105 free( p_dec->p_sys );
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
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 )
140 decoder_sys_t *p_sys = p_dec->p_sys;
142 block_t *p_aout_buffer;
143 int i_frame_length, i_bits;
145 p_block = Parse( p_dec, &i_frame_length, &i_bits, pp_block, false );
149 p_aout_buffer = decoder_NewAudioBuffer( p_dec, i_frame_length );
150 if( p_aout_buffer == NULL )
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;
157 p_block->i_buffer -= AES3_HEADER_LEN;
158 p_block->p_buffer += AES3_HEADER_LEN;
160 #ifdef WORDS_BIGENGIAN
170 uint8_t *p_out = p_aout_buffer->p_buffer;
172 while( p_block->i_buffer / 7 )
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]];
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);
187 p_block->i_buffer -= 7;
188 p_block->p_buffer += 7;
192 else if( i_bits == 20 )
194 uint8_t *p_out = p_aout_buffer->p_buffer;
196 while( p_block->i_buffer / 6 )
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);
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);
212 p_block->i_buffer -= 6;
213 p_block->p_buffer += 6;
220 uint8_t *p_out = p_aout_buffer->p_buffer;
222 assert( i_bits == 16 );
224 while( p_block->i_buffer / 5 )
226 p_out[LOB] = reverse[p_block->p_buffer[0]];
227 p_out[HIB] = reverse[p_block->p_buffer[1]];
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);
236 p_block->i_buffer -= 5;
237 p_block->p_buffer += 5;
242 block_Release( p_block );
243 return p_aout_buffer;
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 )
253 decoder_sys_t *p_sys = p_dec->p_sys;
255 int i_frame_length, i_bits;
257 p_block = Parse( p_dec, &i_frame_length, &i_bits, pp_block, true );
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;
264 /* Just pass on the incoming frame */
268 /*****************************************************************************
270 ****************************************************************************/
271 static int Open( decoder_t *p_dec, bool b_packetizer )
273 decoder_sys_t *p_sys;
275 if( p_dec->fmt_in.i_codec != VLC_CODEC_302M )
278 /* Allocate the memory needed to store the decoder's structure */
279 p_dec->p_sys = p_sys = malloc( sizeof(decoder_sys_t) );
281 if( unlikely( !p_sys ) )
285 date_Init( &p_sys->end_date, 48000, 1 );
286 date_Set( &p_sys->end_date, 0 );
288 /* Set output properties */
289 p_dec->fmt_out.i_cat = AUDIO_ES;
290 p_dec->fmt_out.audio.i_rate = 48000;
295 p_dec->fmt_out.i_codec = VLC_CODEC_302M;
297 p_dec->pf_decode_audio = NULL;
298 p_dec->pf_packetize = Packetize;
302 p_dec->fmt_out.i_codec = VLC_CODEC_S16N;
303 p_dec->fmt_out.audio.i_bitspersample = 16;
305 p_dec->pf_decode_audio = Decode;
306 p_dec->pf_packetize = NULL;
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,
324 static block_t *Parse( decoder_t *p_dec, int *pi_frame_length, int *pi_bits,
325 block_t **pp_block, bool b_packetizer )
327 decoder_sys_t *p_sys = p_dec->p_sys;
334 if( !pp_block || !*pp_block ) return NULL;
337 *pp_block = NULL; /* So the packet doesn't get re-sent */
339 /* Date management */
340 if( p_block->i_pts > VLC_TS_INVALID &&
341 p_block->i_pts != date_Get( &p_sys->end_date ) )
343 date_Set( &p_sys->end_date, p_block->i_pts );
346 if( !date_Get( &p_sys->end_date ) )
348 /* We've just started the stream, wait for the first PTS. */
349 block_Release( p_block );
353 if( p_block->i_buffer <= AES3_HEADER_LEN )
355 msg_Err(p_dec, "frame is too short");
356 block_Release( p_block );
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 );
374 if( AES3_HEADER_LEN + i_size != p_block->i_buffer || i_bits > 24 )
376 msg_Err(p_dec, "frame has invalid header");
377 block_Release( p_block );
381 /* Set output properties */
384 p_dec->fmt_out.audio.i_bitspersample = i_bits;
388 p_dec->fmt_out.i_codec = i_bits == 16 ? VLC_CODEC_S16N
390 p_dec->fmt_out.audio.i_bitspersample = i_bits == 16 ? 16 : 24;
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];
397 *pi_frame_length = (p_block->i_buffer - AES3_HEADER_LEN) / ( (4+i_bits) * i_channels / 8 );