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