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 /*****************************************************************************
25 *****************************************************************************/
30 #include <vlc_common.h>
31 #include <vlc_plugin.h>
32 #include <vlc_codec.h>
35 /*****************************************************************************
37 *****************************************************************************/
38 static int OpenDecoder ( vlc_object_t
* );
39 static int OpenPacketizer( vlc_object_t
* );
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
)
50 set_description( N_("AES3/SMPTE 302M audio packetizer") )
51 set_capability( "packetizer", 100 )
52 set_callback( OpenPacketizer
)
56 /*****************************************************************************
57 * decoder_sys_t : aes3 decoder descriptor
58 *****************************************************************************/
67 #define AES3_HEADER_LEN 4
69 /*****************************************************************************
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 /*****************************************************************************
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 /*****************************************************************************
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 );
135 return VLCDEC_SUCCESS
;
137 if( decoder_UpdateAudioFormat( p_dec
) )
139 p_aout_buffer
= NULL
;
143 p_aout_buffer
= decoder_NewAudioBuffer( p_dec
, i_frame_length
);
144 if( p_aout_buffer
== NULL
)
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
;
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;
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;
210 block_Release( p_block
);
211 if( p_aout_buffer
!= NULL
)
212 decoder_QueueAudio( p_dec
, p_aout_buffer
);
213 return VLCDEC_SUCCESS
;
216 /*****************************************************************************
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
;
235 int i_frame_length
, i_bits
;
237 if( !pp_block
) /* No Drain */
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 );
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 */
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
)
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
) )
270 date_Init( &p_sys
->end_date
, 48000, 1 );
272 /* Set output properties */
273 p_dec
->fmt_out
.audio
.i_rate
= 48000;
278 p_dec
->fmt_out
.i_codec
= VLC_CODEC_302M
;
280 p_dec
->pf_packetize
= Packetize
;
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
;
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
;
316 if( !p_block
) /* No drain */
319 if( p_block
->i_flags
& (BLOCK_FLAG_CORRUPTED
|BLOCK_FLAG_DISCONTINUITY
) )
322 if( p_block
->i_flags
& BLOCK_FLAG_CORRUPTED
)
324 block_Release( p_block
);
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
);
343 if( p_block
->i_buffer
<= AES3_HEADER_LEN
)
345 msg_Err(p_dec
, "frame is too short");
346 block_Release( p_block
);
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
);
371 /* Set output properties */
374 p_dec
->fmt_out
.audio
.i_bitspersample
= i_bits
;
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 );