1 /*****************************************************************************
2 * a52.c: ATSC A/52 aka AC-3 decoder plugin for VLC.
3 * This plugin makes use of liba52 to decode A/52 audio
4 * (http://liba52.sf.net/).
5 *****************************************************************************
6 * Copyright (C) 2001-2009 VLC authors and VideoLAN
9 * Authors: Gildas Bazin <gbazin@videolan.org>
10 * Christophe Massiot <massiot@via.ecp.fr>
11 * Thomas Guillem <thomas@gllm.fr>
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU Lesser General Public License as published by
15 * the Free Software Foundation; either version 2.1 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this program; if not, write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 *****************************************************************************/
28 /*****************************************************************************
29 * NOTA BENE: this module requires the linking against a library which is
30 * known to require licensing under the GNU General Public License version 2
31 * (or later). Therefore, the result of compiling this module will normally
32 * be subject to the terms of that later license.
33 *****************************************************************************/
39 #include <vlc_common.h>
40 #include <vlc_plugin.h>
43 #include <stdint.h> /* int16_t .. */
45 #ifdef USE_A52DEC_TREE /* liba52 header file */
46 # include "include/a52.h"
48 # include "a52dec/a52.h"
52 #include <vlc_block.h>
53 #include <vlc_codec.h>
55 static int Open ( vlc_object_t
* );
56 static void Close( vlc_object_t
* );
60 a52_state_t
*p_liba52
; /* liba52 internal structure */
61 bool b_dynrng
; /* see below */
62 int i_flags
; /* liba52 flags, see a52dec/doc/liba52.txt */
64 int i_nb_channels
; /* number of float32 per sample */
66 uint8_t pi_chan_table
[AOUT_CHAN_MAX
]; /* channel reordering */
70 #define DYNRNG_TEXT N_("A/52 dynamic range compression")
71 #define DYNRNG_LONGTEXT N_( \
72 "Dynamic range compression makes the loud sounds softer, and the soft " \
73 "sounds louder, so you can more easily listen to the stream in a noisy " \
74 "environment without disturbing anyone. If you disable the dynamic range "\
75 "compression the playback will be more adapted to a movie theater or a " \
79 set_shortname( "A/52" )
80 set_description( N_("ATSC A/52 (AC-3) audio decoder") )
81 set_category( CAT_INPUT
)
82 set_subcategory( SUBCAT_INPUT_ACODEC
)
83 add_bool( "a52-dynrng", true, DYNRNG_TEXT
, DYNRNG_LONGTEXT
, false )
84 set_capability( "audio decoder", 60 )
85 set_callbacks( Open
, Close
)
89 * helper function to interleave channels
91 static void Interleave( sample_t
*restrict p_out
, const sample_t
*restrict p_in
,
92 unsigned i_nb_channels
, uint8_t *restrict pi_chan_table
)
94 /* We do not only have to interleave, but also reorder the channels */
95 for( unsigned j
= 0; j
< i_nb_channels
; j
++ )
97 for( unsigned i
= 0; i
< 256; i
++ )
100 union { uint32_t u
; int32_t i
; } spl
;
102 spl
.u
= ((uint32_t)p_in
[j
* 256 + i
]) << 4;
103 p_out
[i
* i_nb_channels
+ pi_chan_table
[j
]] = spl
.i
;
105 p_out
[i
* i_nb_channels
+ pi_chan_table
[j
]] = p_in
[j
* 256 + i
];
112 * helper function to duplicate a unique channel
114 static void Duplicate( sample_t
*restrict p_out
, const sample_t
*restrict p_in
)
116 for( unsigned i
= 256; i
--; )
119 union { uint32_t u
; int32_t i
; } spl
;
121 spl
.u
= ((uint32_t)*(p_in
++)) << 4;
125 sample_t s
= *(p_in
++);
133 static int Decode( decoder_t
*p_dec
, block_t
*p_in_buf
)
135 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
137 if (p_in_buf
== NULL
) /* No drain */
138 return VLCDEC_SUCCESS
;
141 sample_t i_sample_level
= (1 << 24);
143 sample_t i_sample_level
= 1;
145 int i_flags
= p_sys
->i_flags
;
146 size_t i_bytes_per_block
= 256 * p_sys
->i_nb_channels
* sizeof(sample_t
);
149 /* Every A/52 frame is composed of 6 blocks, each with an output of 256
150 * samples for each channel. */
151 block_t
*p_out_buf
= block_Alloc( 6 * i_bytes_per_block
);
152 if( unlikely(p_out_buf
== NULL
) )
154 block_Release( p_in_buf
);
155 return VLCDEC_SUCCESS
;
158 /* Do the actual decoding now. */
159 a52_frame( p_sys
->p_liba52
, p_in_buf
->p_buffer
,
160 &i_flags
, &i_sample_level
, 0 );
162 if ( (i_flags
& A52_CHANNEL_MASK
) != (p_sys
->i_flags
& A52_CHANNEL_MASK
)
163 && !p_sys
->b_dontwarn
)
166 "liba52 couldn't do the requested downmix 0x%x->0x%x",
167 p_sys
->i_flags
& A52_CHANNEL_MASK
,
168 i_flags
& A52_CHANNEL_MASK
);
170 p_sys
->b_dontwarn
= 1;
173 if( !p_sys
->b_dynrng
)
175 a52_dynrng( p_sys
->p_liba52
, NULL
, NULL
);
178 for( unsigned i
= 0; i
< 6; i
++ )
180 if( a52_block( p_sys
->p_liba52
) )
181 msg_Warn( p_dec
, "a52_block failed for block %d", i
);
183 sample_t
*p_samples
= a52_samples( p_sys
->p_liba52
);
185 if ( ((p_sys
->i_flags
& A52_CHANNEL_MASK
) == A52_CHANNEL1
186 || (p_sys
->i_flags
& A52_CHANNEL_MASK
) == A52_CHANNEL2
187 || (p_sys
->i_flags
& A52_CHANNEL_MASK
) == A52_MONO
)
188 && (p_dec
->fmt_out
.audio
.i_physical_channels
189 & (AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
)) )
191 Duplicate( (sample_t
*)(p_out_buf
->p_buffer
+ i
* i_bytes_per_block
),
196 /* Interleave the *$£%ù samples. */
197 Interleave( (sample_t
*)(p_out_buf
->p_buffer
+ i
* i_bytes_per_block
),
198 p_samples
, p_sys
->i_nb_channels
, p_sys
->pi_chan_table
);
202 p_out_buf
->i_nb_samples
= A52_FRAME_NB
; /* 6 * 256 */
203 p_out_buf
->i_dts
= p_in_buf
->i_dts
;
204 p_out_buf
->i_pts
= p_in_buf
->i_pts
;
205 p_out_buf
->i_length
= p_in_buf
->i_length
;
206 block_Release( p_in_buf
);
207 decoder_QueueAudio( p_dec
, p_out_buf
);
208 return VLCDEC_SUCCESS
;
211 static int channels_vlc2a52( const audio_format_t
*p_audio
, int *p_flags
)
215 switch ( p_audio
->i_physical_channels
& ~AOUT_CHAN_LFE
)
217 case AOUT_CHAN_CENTER
:
218 if ( (p_audio
->i_physical_channels
& AOUT_CHAN_CENTER
)
219 || (p_audio
->i_physical_channels
220 & (AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
)) )
222 else if ( p_audio
->i_physical_channels
& AOUT_CHAN_LEFT
)
223 i_flags
= A52_CHANNEL1
;
225 i_flags
= A52_CHANNEL2
;
228 case AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
:
229 if ( p_audio
->i_chan_mode
& AOUT_CHANMODE_DOLBYSTEREO
)
231 else if ( p_audio
->i_chan_mode
& AOUT_CHANMODE_DUALMONO
)
232 i_flags
= A52_CHANNEL
;
233 else if ( !(p_audio
->i_physical_channels
& AOUT_CHAN_RIGHT
) )
234 i_flags
= A52_CHANNEL1
;
235 else if ( !(p_audio
->i_physical_channels
& AOUT_CHAN_LEFT
) )
236 i_flags
= A52_CHANNEL2
;
238 i_flags
= A52_STEREO
;
241 case AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
:
245 case AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_REARCENTER
:
249 case AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
250 | AOUT_CHAN_REARCENTER
:
254 case AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
255 | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT
:
259 case AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
260 | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT
:
268 if ( p_audio
->i_physical_channels
& AOUT_CHAN_LFE
)
274 static int Open( vlc_object_t
*p_this
)
276 decoder_t
*p_dec
= (decoder_t
*)p_this
;
277 decoder_sys_t
*p_sys
;
279 if( p_dec
->fmt_in
.i_codec
!= VLC_CODEC_A52
280 || p_dec
->fmt_in
.audio
.i_rate
== 0
281 || p_dec
->fmt_in
.audio
.i_physical_channels
== 0
282 || p_dec
->fmt_in
.audio
.i_bytes_per_frame
== 0
283 || p_dec
->fmt_in
.audio
.i_frame_length
== 0 )
286 /* Allocate the memory needed to store the module's structure */
287 p_dec
->p_sys
= p_sys
= malloc( sizeof(decoder_sys_t
) );
291 p_sys
->b_dynrng
= var_InheritBool( p_this
, "a52-dynrng" );
292 p_sys
->b_dontwarn
= 0;
294 p_sys
->i_nb_channels
= aout_FormatNbChannels( &p_dec
->fmt_in
.audio
);
295 if( channels_vlc2a52( &p_dec
->fmt_in
.audio
, &p_sys
->i_flags
)
298 msg_Warn( p_this
, "unknown sample format!" );
302 p_sys
->i_flags
|= A52_ADJUST_LEVEL
;
304 /* Initialize liba52 */
305 p_sys
->p_liba52
= a52_init( 0 );
306 if( p_sys
->p_liba52
== NULL
)
308 msg_Err( p_this
, "unable to initialize liba52" );
313 static const uint32_t pi_channels_in
[] = {
314 AOUT_CHAN_LFE
, AOUT_CHAN_LEFT
, AOUT_CHAN_CENTER
, AOUT_CHAN_RIGHT
,
315 AOUT_CHAN_REARLEFT
, AOUT_CHAN_REARCENTER
, AOUT_CHAN_REARRIGHT
, 0
318 aout_CheckChannelReorder( pi_channels_in
, NULL
,
319 p_dec
->fmt_in
.audio
.i_physical_channels
,
320 p_sys
->pi_chan_table
);
322 p_dec
->fmt_out
.audio
= p_dec
->fmt_in
.audio
;
324 p_dec
->fmt_out
.audio
.i_format
= VLC_CODEC_S32N
;
326 p_dec
->fmt_out
.audio
.i_format
= VLC_CODEC_FL32
;
328 p_dec
->fmt_out
.i_codec
= p_dec
->fmt_out
.audio
.i_format
;
330 aout_FormatPrepare( &p_dec
->fmt_out
.audio
);
332 if( decoder_UpdateAudioFormat( p_dec
) )
338 p_dec
->pf_decode
= Decode
;
339 p_dec
->pf_flush
= NULL
;
343 static void Close( vlc_object_t
*p_this
)
345 decoder_t
*p_dec
= (decoder_t
*)p_this
;
346 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
348 a52_free( p_sys
->p_liba52
);