1 /*****************************************************************************
2 * dts_header.c: parse DTS audio headers info
3 *****************************************************************************
4 * Copyright (C) 2004-2009 VLC authors and VideoLAN
7 * Authors: Gildas Bazin <gbazin@netcourrier.com>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
29 #include <vlc_common.h>
33 #include "dts_header.h"
37 static void BufLeToBe( uint8_t *p_out
, const uint8_t *p_in
, int i_in
)
41 for( i
= 0; i
< i_in
/2; i
++ )
43 p_out
[i
*2] = p_in
[i
*2+1];
44 p_out
[i
*2+1] = p_in
[i
*2];
48 static int Buf14To16( uint8_t *p_out
, const uint8_t *p_in
, int i_in
, int i_le
)
50 unsigned char tmp
, cur
= 0;
51 int bits_in
, bits_out
= 0;
54 for( i
= 0; i
< i_in
; i
++ )
63 tmp
= p_in
[i
+i_le
] & 0x3F;
69 int need
= __MIN( 8 - bits_out
, bits_in
);
71 cur
|= ( tmp
>> (bits_in
- need
) );
72 tmp
<<= (8 - bits_in
+ need
);
73 tmp
>>= (8 - bits_in
+ need
);
94 enum dts_bitsteam_type
{
97 DTS_SYNC_CORE_14BITS_BE
,
98 DTS_SYNC_CORE_14BITS_LE
,
102 static bool dts_header_IsSync( const uint8_t *p_buf
,
103 enum dts_bitsteam_type
*p_bitstream_type
)
105 if( memcmp( p_buf
, "\x7F\xFE\x80\x01", 4 ) == 0 )
106 *p_bitstream_type
= DTS_SYNC_CORE_BE
;
108 if( memcmp( p_buf
, "\xFE\x7F\x01\x80", 4 ) == 0 )
109 *p_bitstream_type
= DTS_SYNC_CORE_LE
;
111 if( memcmp( p_buf
, "\x64\x58\x20\x25", 4 ) == 0 )
112 *p_bitstream_type
= DTS_SYNC_SUBSTREAM
;
114 if( memcmp( p_buf
, "\x1F\xFF\xE8\x00", 4 ) == 0
115 && p_buf
[4] == 0x07 && (p_buf
[5] & 0xf0) == 0xf0 )
116 *p_bitstream_type
= DTS_SYNC_CORE_14BITS_BE
;
118 if( memcmp( p_buf
, "\xFF\x1F\x00\xE8", 4 ) == 0
119 && (p_buf
[4] & 0xf0) == 0xf0 && p_buf
[5] == 0x07 )
120 *p_bitstream_type
= DTS_SYNC_CORE_14BITS_LE
;
126 bool vlc_dts_header_IsSync( const void *p_buf
, size_t i_buf
)
129 && dts_header_IsSync( p_buf
, &(enum dts_bitsteam_type
) { 0 } );
132 static unsigned int dca_get_samplerate( uint8_t i_sfreq
)
134 /* See ETSI TS 102 114, table 5-5 */
135 const unsigned int p_dca_samplerates
[16] = {
136 0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0,
137 12000, 24000, 48000, 96000, 192000
142 return p_dca_samplerates
[i_sfreq
];
145 static unsigned int dca_get_bitrate( uint8_t i_rate
)
147 /* See ETSI TS 102 114, table 5-7 */
148 const unsigned int p_dca_bitrates
[32] = {
149 32000, 56000, 64000, 96000, 112000,
150 128000, 192000, 224000, 256000, 320000,
151 384000, 448000, 512000, 576000, 640000,
152 768000, 896000, 1024000, 1152000, 1280000,
153 1344000, 1408000, 1411200, 1472000, 1536000,
154 1920000, 2048000, 3072000, 3840000,
155 /* FIXME: The following can't be put in a VLC audio_format_t:
156 * 1: open, 2: variable, 3: lossless */
162 return p_dca_bitrates
[i_rate
];
165 static uint16_t dca_get_channels( uint8_t i_amode
, bool b_lfe
,
166 uint16_t *p_chan_mode
)
168 /* See ETSI TS 102 114, table 5-4
170 * 01: A + B (dual mono)
172 * 03: (L+R) + (L-R) (sum and difference)
173 * 04: LT + RT (left and right total)
177 * 08: L + R + SL + SR
178 * 09: C + L + R + SL + SR
179 * 0A: CL + CR + L + R + SL + SR
180 * 0B: C + L + R + LR + RR + OV
181 * 0C: CF + CR + LF + RF + LR + RR
182 * 0D: CL + C + CR + L + R + SL + SR
183 * 0E: CL + CR + L + R + SL1 + SL2 + SR1 + SR2
184 * 0F: CL + C + CR + L + R + SL + S + SR
185 * 10-3F: user defined */
187 uint16_t i_physical_channels
;
192 i_physical_channels
= AOUT_CHAN_CENTER
;
195 i_physical_channels
= AOUT_CHANS_FRONT
;
196 *p_chan_mode
= AOUT_CHANMODE_DUALMONO
;
201 i_physical_channels
= AOUT_CHANS_FRONT
;
204 i_physical_channels
= AOUT_CHANS_3_0
;
207 i_physical_channels
= AOUT_CHANS_FRONT
| AOUT_CHAN_REARCENTER
;
210 i_physical_channels
= AOUT_CHANS_4_CENTER_REAR
;
213 i_physical_channels
= AOUT_CHANS_4_0
;
216 i_physical_channels
= AOUT_CHANS_5_0
;
220 i_physical_channels
= AOUT_CHANS_6_0
;
223 i_physical_channels
= AOUT_CHANS_CENTER
| AOUT_CHANS_FRONT
227 i_physical_channels
= AOUT_CHANS_7_0
;
231 /* FIXME: AOUT_CHANS_8_0 */
232 i_physical_channels
= AOUT_CHANS_7_0
;
238 i_physical_channels
|= AOUT_CHAN_LFE
;
240 return i_physical_channels
;
243 static int dts_header_ParseSubstream( vlc_dts_header_t
*p_header
,
244 const void *p_buffer
)
247 bs_init( &s
, p_buffer
, VLC_DTS_HEADER_SIZE
);
248 bs_skip( &s
, 32 /*SYNCEXTSSH*/ + 8 /*UserDefinedBits*/ + 2 /*nExtSSIndex*/ );
249 uint8_t bHeaderSizeType
= bs_read1( &s
);
250 uint32_t nuBits4ExSSFsize
;
251 if( bHeaderSizeType
== 0 )
253 bs_skip( &s
, 8 /*nuBits4Header*/ );
254 nuBits4ExSSFsize
= bs_read( &s
, 16 );
258 bs_skip( &s
, 12 /*nuBits4Header*/ );
259 nuBits4ExSSFsize
= bs_read( &s
, 20 );
261 memset( p_header
, 0, sizeof(*p_header
) );
262 p_header
->b_substream
= true;
263 p_header
->i_frame_size
= nuBits4ExSSFsize
+ 1;
267 static int dts_header_ParseCore( vlc_dts_header_t
*p_header
,
268 const void *p_buffer
, bool b_14b
)
271 bs_init( &s
, p_buffer
, VLC_DTS_HEADER_SIZE
);
272 bs_skip( &s
, 32 /*SYNC*/ + 1 /*FTYPE*/ + 5 /*SHORT*/ + 1 /*CPF*/ );
273 uint8_t i_nblks
= bs_read( &s
, 7 );
276 uint16_t i_fsize
= bs_read( &s
, 14 );
279 uint8_t i_amode
= bs_read( &s
, 6 );
280 uint8_t i_sfreq
= bs_read( &s
, 4 );
281 uint8_t i_rate
= bs_read( &s
, 5 );
282 bs_skip( &s
, 1 /*FixedBit*/ + 1 /*DYNF*/ + 1 /*TIMEF*/ + 1 /*AUXF*/ +
283 1 /*HDCD*/ + 3 /*EXT_AUDIO_ID*/ + 1 /*EXT_AUDIO */ + 1 /*ASPF*/ );
284 uint8_t i_lff
= bs_read( &s
, 2 );
286 bool b_lfe
= i_lff
== 1 || i_lff
== 2;
288 p_header
->b_substream
= false;
289 p_header
->i_rate
= dca_get_samplerate( i_sfreq
);
290 p_header
->i_bitrate
= dca_get_bitrate( i_rate
);
291 p_header
->i_frame_size
= !b_14b
? ( i_fsize
+ 1 )
292 : ( i_fsize
+ 1 ) * 16 / 14;
293 /* See ETSI TS 102 114, table 5-2 */
294 p_header
->i_frame_length
= (i_nblks
+ 1) * 32;
295 p_header
->i_chan_mode
= 0;
296 p_header
->i_physical_channels
=
297 dca_get_channels( i_amode
, b_lfe
, &p_header
->i_chan_mode
);
299 if( !p_header
->i_rate
|| !p_header
->i_frame_size
||
300 !p_header
->i_frame_length
|| !p_header
->i_physical_channels
)
306 int vlc_dts_header_Parse( vlc_dts_header_t
*p_header
,
307 const void *p_buffer
, size_t i_buffer
)
309 enum dts_bitsteam_type bitstream_type
;
311 if( i_buffer
< VLC_DTS_HEADER_SIZE
)
314 if( !dts_header_IsSync( p_buffer
, &bitstream_type
) )
317 switch( bitstream_type
)
319 case DTS_SYNC_CORE_LE
:
321 uint8_t conv_buf
[VLC_DTS_HEADER_SIZE
];
322 BufLeToBe( conv_buf
, p_buffer
, VLC_DTS_HEADER_SIZE
);
323 return dts_header_ParseCore( p_header
, conv_buf
, false );
325 case DTS_SYNC_CORE_BE
:
326 return dts_header_ParseCore( p_header
, p_buffer
, false );
327 case DTS_SYNC_CORE_14BITS_BE
:
328 case DTS_SYNC_CORE_14BITS_LE
:
330 uint8_t conv_buf
[VLC_DTS_HEADER_SIZE
];
331 Buf14To16( conv_buf
, p_buffer
, VLC_DTS_HEADER_SIZE
,
332 bitstream_type
== DTS_SYNC_CORE_14BITS_LE
);
333 return dts_header_ParseCore( p_header
, conv_buf
, true );
335 case DTS_SYNC_SUBSTREAM
:
336 return dts_header_ParseSubstream( p_header
, p_buffer
);
338 vlc_assert_unreachable();