codec: subsdec: fix variable shadowing
[vlc.git] / modules / codec / aes3.c
blob869b1d37000af9952610fdba9e1d1f0bee0b92c6
1 /*****************************************************************************
2 * aes3.c: aes3 decoder/packetizer module
3 *****************************************************************************
4 * Copyright (C) 2008 VLC authors and VideoLAN
5 * $Id$
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 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_codec.h>
34 #include <assert.h>
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 * );
43 vlc_module_begin ()
45 set_category( CAT_INPUT )
46 set_subcategory( SUBCAT_INPUT_ACODEC )
47 set_description( N_("AES3/SMPTE 302M audio decoder") )
48 set_capability( "audio decoder", 100 )
49 set_callbacks( OpenDecoder, Close )
51 add_submodule ()
52 set_description( N_("AES3/SMPTE 302M audio packetizer") )
53 set_capability( "packetizer", 100 )
54 set_callbacks( OpenPacketizer, Close )
56 vlc_module_end ()
58 /*****************************************************************************
59 * decoder_sys_t : aes3 decoder descriptor
60 *****************************************************************************/
61 typedef struct
64 * Output properties
66 date_t end_date;
67 } decoder_sys_t;
69 #define AES3_HEADER_LEN 4
71 /*****************************************************************************
72 * Local prototypes
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 *p_block, bool b_packetizer );
79 /*****************************************************************************
80 * OpenDecoder:
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 /*****************************************************************************
90 * OpenPacketizer:
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 int Decode( decoder_t *p_dec, block_t *p_block )
140 decoder_sys_t *p_sys = p_dec->p_sys;
141 block_t *p_aout_buffer;
142 int i_frame_length, i_bits;
144 p_block = Parse( p_dec, &i_frame_length, &i_bits, p_block, false );
145 if( !p_block )
146 return VLCDEC_SUCCESS;
148 if( decoder_UpdateAudioFormat( p_dec ) )
150 p_aout_buffer = NULL;
151 goto exit;
154 p_aout_buffer = decoder_NewAudioBuffer( p_dec, i_frame_length );
155 if( p_aout_buffer == NULL )
156 goto exit;
158 p_aout_buffer->i_pts = date_Get( &p_sys->end_date );
159 p_aout_buffer->i_length = date_Increment( &p_sys->end_date,
160 i_frame_length ) - p_aout_buffer->i_pts;
162 p_block->i_buffer -= AES3_HEADER_LEN;
163 p_block->p_buffer += AES3_HEADER_LEN;
165 if( i_bits == 24 )
167 uint32_t *p_out = (uint32_t *)p_aout_buffer->p_buffer;
169 while( p_block->i_buffer / 7 )
171 *(p_out++) = (reverse[p_block->p_buffer[0]] << 8)
172 | (reverse[p_block->p_buffer[1]] << 16)
173 | (reverse[p_block->p_buffer[2]] << 24);
174 *(p_out++) = ((reverse[p_block->p_buffer[3]] << 4)
175 | (reverse[p_block->p_buffer[4]] << 12)
176 | (reverse[p_block->p_buffer[5]] << 20)
177 | (reverse[p_block->p_buffer[6]] << 28)) & 0xFFFFFF00;
179 p_block->i_buffer -= 7;
180 p_block->p_buffer += 7;
184 else if( i_bits == 20 )
186 uint32_t *p_out = (uint32_t *)p_aout_buffer->p_buffer;
188 while( p_block->i_buffer / 6 )
190 *(p_out++) = (reverse[p_block->p_buffer[0]] << 12)
191 | (reverse[p_block->p_buffer[1]] << 20)
192 | (reverse[p_block->p_buffer[2]] << 28);
193 *(p_out++) = (reverse[p_block->p_buffer[3]] << 12)
194 | (reverse[p_block->p_buffer[4]] << 20)
195 | (reverse[p_block->p_buffer[5]] << 28);
197 p_block->i_buffer -= 6;
198 p_block->p_buffer += 6;
201 else
203 uint16_t *p_out = (uint16_t *)p_aout_buffer->p_buffer;
205 assert( i_bits == 16 );
207 while( p_block->i_buffer / 5 )
209 *(p_out++) = reverse[p_block->p_buffer[0]]
210 |(reverse[p_block->p_buffer[1]] << 8);
211 *(p_out++) = (reverse[p_block->p_buffer[2]] >> 4)
212 | (reverse[p_block->p_buffer[3]] << 4)
213 | (reverse[p_block->p_buffer[4]] << 12);
215 p_block->i_buffer -= 5;
216 p_block->p_buffer += 5;
220 exit:
221 block_Release( p_block );
222 if( p_aout_buffer != NULL )
223 decoder_QueueAudio( p_dec, p_aout_buffer );
224 return VLCDEC_SUCCESS;
227 /*****************************************************************************
228 * Flush:
229 *****************************************************************************/
230 static void Flush( decoder_t *p_dec )
232 decoder_sys_t *p_sys = p_dec->p_sys;
234 date_Set( &p_sys->end_date, VLC_TICK_INVALID );
237 /*****************************************************************************
238 * Packetize: packetizes an aes3 frame.
239 ****************************************************************************
240 * Beware, this function must be fed with complete frames (PES packet).
241 *****************************************************************************/
242 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
244 decoder_sys_t *p_sys = p_dec->p_sys;
245 block_t *p_block;
246 int i_frame_length, i_bits;
248 if( !pp_block ) /* No Drain */
249 return NULL;
250 p_block = *pp_block;
251 *pp_block = NULL; /* So the packet doesn't get re-sent */
253 p_block = Parse( p_dec, &i_frame_length, &i_bits, p_block, true );
254 if( !p_block )
255 return NULL;
257 p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date );
258 p_block->i_length = date_Increment( &p_sys->end_date, i_frame_length ) - p_block->i_pts;
260 /* Just pass on the incoming frame */
261 return p_block;
264 /*****************************************************************************
266 ****************************************************************************/
267 static int Open( decoder_t *p_dec, bool b_packetizer )
269 decoder_sys_t *p_sys;
271 if( p_dec->fmt_in.i_codec != VLC_CODEC_302M )
272 return VLC_EGENERIC;
274 /* Allocate the memory needed to store the decoder's structure */
275 p_dec->p_sys = p_sys = malloc( sizeof(decoder_sys_t) );
277 if( unlikely( !p_sys ) )
278 return VLC_EGENERIC;
280 /* Misc init */
281 date_Init( &p_sys->end_date, 48000, 1 );
283 /* Set output properties */
284 p_dec->fmt_out.audio.i_rate = 48000;
286 /* Set callback */
287 if( b_packetizer )
289 p_dec->fmt_out.i_codec = VLC_CODEC_302M;
291 p_dec->pf_packetize = Packetize;
293 else
295 p_dec->fmt_out.i_codec = VLC_CODEC_S16N;
296 p_dec->fmt_out.audio.i_bitspersample = 16;
298 p_dec->pf_decode = Decode;
300 p_dec->pf_flush = Flush;
301 return VLC_SUCCESS;
304 static const unsigned int pi_original_channels[4] = {
305 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
306 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
307 AOUT_CHAN_CENTER | AOUT_CHAN_LFE,
308 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
309 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
310 AOUT_CHAN_CENTER | AOUT_CHAN_LFE,
311 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
312 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
313 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
314 AOUT_CHAN_CENTER | AOUT_CHAN_LFE,
317 static block_t * Parse( decoder_t *p_dec, int *pi_frame_length, int *pi_bits,
318 block_t *p_block, bool b_packetizer )
320 decoder_sys_t *p_sys = p_dec->p_sys;
321 uint32_t h;
322 unsigned int i_size;
323 int i_channels;
324 int i_bits;
326 if( !p_block ) /* No drain */
327 return NULL;
329 if( p_block->i_flags & (BLOCK_FLAG_CORRUPTED|BLOCK_FLAG_DISCONTINUITY) )
331 Flush( p_dec );
332 if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
334 block_Release( p_block );
335 return NULL;
339 /* Date management */
340 if( p_block->i_pts != VLC_TICK_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 ) == VLC_TICK_INVALID )
348 /* We've just started the stream, wait for the first PTS. */
349 block_Release( p_block );
350 return NULL;
353 if( p_block->i_buffer <= AES3_HEADER_LEN )
355 msg_Err(p_dec, "frame is too short");
356 block_Release( p_block );
357 return NULL;
361 * AES3 header :
362 * size: 16
363 * number channels 2
364 * channel_id 8
365 * bits per samples 2
366 * alignments 4
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 );
378 return NULL;
381 /* Set output properties */
382 if( b_packetizer )
384 p_dec->fmt_out.audio.i_bitspersample = i_bits;
386 else
388 p_dec->fmt_out.i_codec = i_bits == 16 ? VLC_CODEC_S16N : VLC_CODEC_S32N;
389 p_dec->fmt_out.audio.i_bitspersample = i_bits == 16 ? 16 : 32;
392 p_dec->fmt_out.audio.i_channels = i_channels;
393 p_dec->fmt_out.audio.i_physical_channels = pi_original_channels[i_channels/2-1];
395 *pi_frame_length = (p_block->i_buffer - AES3_HEADER_LEN) / ( (4+i_bits) * i_channels / 8 );
396 *pi_bits = i_bits;
397 return p_block;