1 /*****************************************************************************
2 * dca.c: DTS Coherent Acoustics decoder plugin for VLC.
3 * This plugin makes use of libdca to do the actual decoding
4 * (http://developers.videolan.org/libdca.html).
5 *****************************************************************************
6 * Copyright (C) 2001, 2016 libdca VLC authors and VideoLAN
8 * Author: Gildas Bazin <gbazin@videolan.org>
9 * Thomas Guillem <thomas@gllm.fr>
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 2.1 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
26 /*****************************************************************************
27 * NOTA BENE: this module requires the linking against a library which is
28 * known to require licensing under the GNU General Public License version 2
29 * (or later). Therefore, the result of compiling this module will normally
30 * be subject to the terms of that later license.
31 *****************************************************************************/
37 #include <vlc_common.h>
38 #include <vlc_plugin.h>
40 #include <dca.h> /* libdca header file */
43 #include <vlc_block.h>
44 #include <vlc_codec.h>
46 static int Open ( vlc_object_t
* );
47 static void Close( vlc_object_t
* );
51 dca_state_t
*p_libdca
; /* libdca internal structure */
52 bool b_dynrng
; /* see below */
53 int i_flags
; /* libdca flags, see dtsdec/doc/libdts.txt */
55 int i_nb_channels
; /* number of float32 per sample */
57 uint8_t pi_chan_table
[AOUT_CHAN_MAX
]; /* channel reordering */
61 #define DYNRNG_TEXT N_("DTS dynamic range compression")
62 #define DYNRNG_LONGTEXT N_( \
63 "Dynamic range compression makes the loud sounds softer, and the soft " \
64 "sounds louder, so you can more easily listen to the stream in a noisy " \
65 "environment without disturbing anyone. If you disable the dynamic range "\
66 "compression the playback will be more adapted to a movie theater or a " \
70 set_category( CAT_INPUT
)
71 set_subcategory( SUBCAT_INPUT_ACODEC
)
72 set_shortname( "DCA" )
73 set_description( N_("DTS Coherent Acoustics audio decoder") )
74 add_bool( "dts-dynrng", true, DYNRNG_TEXT
, DYNRNG_LONGTEXT
, false )
75 set_capability( "decoder", 60 )
76 set_callbacks( Open
, Close
)
80 * helper function to interleave channels
82 static void Interleave( float * p_out
, const float * p_in
, int i_nb_channels
,
83 uint8_t *pi_chan_table
)
85 /* We do not only have to interleave, but also reorder the channels. */
88 for ( j
= 0; j
< i_nb_channels
; j
++ )
90 for ( i
= 0; i
< 256; i
++ )
92 p_out
[i
* i_nb_channels
+ pi_chan_table
[j
]] = p_in
[j
* 256 + i
];
98 * helper function to duplicate a unique channel
100 static void Duplicate( float * p_out
, const float * p_in
)
102 for ( int i
= 256; i
--; )
111 * helper function to exchange left & right channels
113 static void Exchange( float * p_out
, const float * p_in
)
115 const float * p_first
= p_in
+ 256;
116 const float * p_second
= p_in
;
118 for ( int i
= 0; i
< 256; i
++ )
120 *p_out
++ = *p_first
++;
121 *p_out
++ = *p_second
++;
125 static int Decode( decoder_t
*p_dec
, block_t
*p_in_buf
)
127 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
129 if (p_in_buf
== NULL
) /* No Drain */
130 return VLCDEC_SUCCESS
;
132 sample_t i_sample_level
= 1;
133 int i_flags
= p_sys
->i_flags
;
134 size_t i_bytes_per_block
= 256 * p_sys
->i_nb_channels
* sizeof(float);
136 block_t
*p_out_buf
= block_Alloc( 6 * i_bytes_per_block
);
137 if( unlikely(p_out_buf
== NULL
) )
141 * Do the actual decoding now.
144 /* Needs to be called so the decoder knows which type of bitstream it is
146 int i_sample_rate
, i_bit_rate
, i_frame_length
;
147 if( !dca_syncinfo( p_sys
->p_libdca
, p_in_buf
->p_buffer
, &i_flags
,
148 &i_sample_rate
, &i_bit_rate
, &i_frame_length
) )
150 msg_Warn( p_dec
, "libdca couldn't sync on frame" );
151 p_out_buf
->i_nb_samples
= p_out_buf
->i_buffer
= 0;
155 i_flags
= p_sys
->i_flags
;
156 dca_frame( p_sys
->p_libdca
, p_in_buf
->p_buffer
,
157 &i_flags
, &i_sample_level
, 0 );
159 if ( (i_flags
& DCA_CHANNEL_MASK
) != (p_sys
->i_flags
& DCA_CHANNEL_MASK
)
160 && !p_sys
->b_dontwarn
)
163 "libdca couldn't do the requested downmix 0x%x->0x%x",
164 p_sys
->i_flags
& DCA_CHANNEL_MASK
,
165 i_flags
& DCA_CHANNEL_MASK
);
167 p_sys
->b_dontwarn
= 1;
170 for( int i
= 0; i
< dca_blocks_num(p_sys
->p_libdca
); i
++ )
172 sample_t
* p_samples
;
174 if( dca_block( p_sys
->p_libdca
) )
176 msg_Warn( p_dec
, "dca_block failed for block %d", i
);
180 p_samples
= dca_samples( p_sys
->p_libdca
);
182 if ( (p_sys
->i_flags
& DCA_CHANNEL_MASK
) == DCA_MONO
183 && (p_dec
->fmt_out
.audio
.i_physical_channels
184 & (AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
)) )
186 Duplicate( (float *)(p_out_buf
->p_buffer
+ i
* i_bytes_per_block
),
189 else if ( p_dec
->fmt_out
.audio
.i_original_channels
190 & AOUT_CHAN_REVERSESTEREO
)
192 Exchange( (float *)(p_out_buf
->p_buffer
+ i
* i_bytes_per_block
),
197 /* Interleave the *$£%ù samples. */
198 Interleave( (float *)(p_out_buf
->p_buffer
+ i
* i_bytes_per_block
),
199 p_samples
, p_sys
->i_nb_channels
, p_sys
->pi_chan_table
);
203 p_out_buf
->i_nb_samples
= dca_blocks_num(p_sys
->p_libdca
) * 256;
204 p_out_buf
->i_buffer
= p_in_buf
->i_nb_samples
* sizeof(float) * p_sys
->i_nb_channels
;
205 p_out_buf
->i_dts
= p_in_buf
->i_dts
;
206 p_out_buf
->i_pts
= p_in_buf
->i_pts
;
207 p_out_buf
->i_length
= p_in_buf
->i_length
;
209 if (p_out_buf
!= NULL
)
210 decoder_QueueAudio(p_dec
, p_out_buf
);
211 block_Release( p_in_buf
);
212 return VLCDEC_SUCCESS
;
215 static int channels_vlc2dca( const audio_format_t
*p_audio
, int *p_flags
)
219 switch ( p_audio
->i_physical_channels
& ~AOUT_CHAN_LFE
)
221 case AOUT_CHAN_CENTER
:
222 if ( (p_audio
->i_original_channels
& AOUT_CHAN_CENTER
)
223 || (p_audio
->i_original_channels
224 & (AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
)) )
228 case AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
:
229 if ( p_audio
->i_original_channels
& AOUT_CHAN_DOLBYSTEREO
)
231 else if ( p_audio
->i_original_channels
== AOUT_CHAN_CENTER
)
233 else if ( p_audio
->i_original_channels
& AOUT_CHAN_DUALMONO
)
234 i_flags
= DCA_CHANNEL
;
236 i_flags
= DCA_STEREO
;
239 case AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
:
243 case AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_REARCENTER
:
247 case AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
248 | AOUT_CHAN_REARCENTER
:
252 case AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
253 | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT
:
257 case AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
258 | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT
:
266 if ( p_audio
->i_physical_channels
& AOUT_CHAN_LFE
)
272 static int Open( vlc_object_t
*p_this
)
274 decoder_t
*p_dec
= (decoder_t
*)p_this
;
275 decoder_sys_t
*p_sys
;
277 if( p_dec
->fmt_in
.i_codec
!= VLC_CODEC_DTS
278 || p_dec
->fmt_in
.audio
.i_rate
== 0
279 || p_dec
->fmt_in
.audio
.i_physical_channels
== 0
280 || p_dec
->fmt_in
.audio
.i_original_channels
== 0
281 || p_dec
->fmt_in
.audio
.i_bytes_per_frame
== 0
282 || p_dec
->fmt_in
.audio
.i_frame_length
== 0 )
285 /* Allocate the memory needed to store the module's structure */
286 p_sys
= p_dec
->p_sys
= malloc( sizeof(decoder_sys_t
) );
290 p_sys
->b_dynrng
= var_InheritBool( p_this
, "dts-dynrng" );
291 p_sys
->b_dontwarn
= 0;
293 /* We'll do our own downmixing, thanks. */
294 p_sys
->i_nb_channels
= aout_FormatNbChannels( &p_dec
->fmt_in
.audio
);
295 if( channels_vlc2dca( &p_dec
->fmt_in
.audio
, &p_sys
->i_flags
)
298 msg_Warn( p_this
, "unknown sample format!" );
302 //p_sys->i_flags |= DCA_ADJUST_LEVEL;
304 /* Initialize libdca */
305 p_sys
->p_libdca
= dca_init( 0 );
306 if( p_sys
->p_libdca
== NULL
)
308 msg_Err( p_this
, "unable to initialize libdca" );
313 /* libdca channel order
314 * libdca currently only decodes 5.1, even if you have a DTS-ES source. */
315 static const uint32_t pi_channels_in
[] = {
316 AOUT_CHAN_CENTER
, AOUT_CHAN_LEFT
, AOUT_CHAN_RIGHT
,
317 AOUT_CHAN_REARCENTER
, AOUT_CHAN_REARLEFT
, AOUT_CHAN_REARRIGHT
,
321 aout_CheckChannelReorder( pi_channels_in
, NULL
,
322 p_dec
->fmt_in
.audio
.i_physical_channels
,
323 p_sys
->pi_chan_table
);
325 p_dec
->fmt_out
.i_cat
= AUDIO_ES
;
326 p_dec
->fmt_out
.audio
= p_dec
->fmt_in
.audio
;
327 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
) )
334 es_format_Init( &p_dec
->fmt_out
, UNKNOWN_ES
, 0 );
339 p_dec
->pf_decode
= Decode
;
340 p_dec
->pf_flush
= NULL
;
344 static void Close( vlc_object_t
*p_this
)
346 decoder_t
*p_dec
= (decoder_t
*)p_this
;
347 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
349 dca_free( p_sys
->p_libdca
);