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;
162 uint32_t *p_out = (uint32_t *)p_aout_buffer->p_buffer;
164 while( p_block->i_buffer / 7 )
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;
174 p_block->i_buffer -= 7;
175 p_block->p_buffer += 7;
179 else if( i_bits == 20 )
181 uint32_t *p_out = (uint32_t *)p_aout_buffer->p_buffer;
183 while( p_block->i_buffer / 6 )
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);
192 p_block->i_buffer -= 6;
193 p_block->p_buffer += 6;
198 uint16_t *p_out = (uint16_t *)p_aout_buffer->p_buffer;
200 assert( i_bits == 16 );
202 while( p_block->i_buffer / 5 )
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);
210 p_block->i_buffer -= 5;
211 p_block->p_buffer += 5;
216 block_Release( p_block );
217 return p_aout_buffer;
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 )
227 decoder_sys_t *p_sys = p_dec->p_sys;
229 int i_frame_length, i_bits;
231 p_block = Parse( p_dec, &i_frame_length, &i_bits, pp_block, true );
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;
238 /* Just pass on the incoming frame */
242 /*****************************************************************************
244 ****************************************************************************/
245 static int Open( decoder_t *p_dec, bool b_packetizer )
247 decoder_sys_t *p_sys;
249 if( p_dec->fmt_in.i_codec != VLC_CODEC_302M )
252 /* Allocate the memory needed to store the decoder's structure */
253 p_dec->p_sys = p_sys = malloc( sizeof(decoder_sys_t) );
255 if( unlikely( !p_sys ) )
259 date_Init( &p_sys->end_date, 48000, 1 );
260 date_Set( &p_sys->end_date, 0 );
262 /* Set output properties */
263 p_dec->fmt_out.i_cat = AUDIO_ES;
264 p_dec->fmt_out.audio.i_rate = 48000;
269 p_dec->fmt_out.i_codec = VLC_CODEC_302M;
271 p_dec->pf_decode_audio = NULL;
272 p_dec->pf_packetize = Packetize;
276 p_dec->fmt_out.i_codec = VLC_CODEC_S16N;
277 p_dec->fmt_out.audio.i_bitspersample = 16;
279 p_dec->pf_decode_audio = Decode;
280 p_dec->pf_packetize = NULL;
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,
298 static block_t *Parse( decoder_t *p_dec, int *pi_frame_length, int *pi_bits,
299 block_t **pp_block, bool b_packetizer )
301 decoder_sys_t *p_sys = p_dec->p_sys;
308 if( !pp_block || !*pp_block ) return NULL;
311 *pp_block = NULL; /* So the packet doesn't get re-sent */
313 /* Date management */
314 if( p_block->i_pts > VLC_TS_INVALID &&
315 p_block->i_pts != date_Get( &p_sys->end_date ) )
317 date_Set( &p_sys->end_date, p_block->i_pts );
320 if( !date_Get( &p_sys->end_date ) )
322 /* We've just started the stream, wait for the first PTS. */
323 block_Release( p_block );
327 if( p_block->i_buffer <= AES3_HEADER_LEN )
329 msg_Err(p_dec, "frame is too short");
330 block_Release( p_block );
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 );
348 if( AES3_HEADER_LEN + i_size != p_block->i_buffer || i_bits > 24 )
350 msg_Err(p_dec, "frame has invalid header");
351 block_Release( p_block );
355 /* Set output properties */
358 p_dec->fmt_out.audio.i_bitspersample = i_bits;
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;
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];
370 *pi_frame_length = (p_block->i_buffer - AES3_HEADER_LEN) / ( (4+i_bits) * i_channels / 8 );