Update translations from 2.2.x branch
[vlc.git] / modules / packetizer / dts_header.c
blob36dd8bac5bebbb89651c437cdb67990b9c9cdfbd
1 /*****************************************************************************
2 * dts_header.c: parse DTS audio headers info
3 *****************************************************************************
4 * Copyright (C) 2004-2009 VLC authors and VideoLAN
5 * $Id$
7 * Authors: Gildas Bazin <gbazin@netcourrier.com>
8 * Laurent Aimar
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 *****************************************************************************/
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
29 #include <vlc_common.h>
30 #include <vlc_bits.h>
31 #include <vlc_aout.h>
33 #include "dts_header.h"
35 #include <assert.h>
37 static void BufLeToBe( uint8_t *p_out, const uint8_t *p_in, int i_in )
39 int i;
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;
52 int i, i_out = 0;
54 for( i = 0; i < i_in; i++ )
56 if( i%2 )
58 tmp = p_in[i-i_le];
59 bits_in = 8;
61 else
63 tmp = p_in[i+i_le] & 0x3F;
64 bits_in = 8 - 2;
67 if( bits_out < 8 )
69 int need = __MIN( 8 - bits_out, bits_in );
70 cur <<= need;
71 cur |= ( tmp >> (bits_in - need) );
72 tmp <<= (8 - bits_in + need);
73 tmp >>= (8 - bits_in + need);
74 bits_in -= need;
75 bits_out += need;
78 if( bits_out == 8 )
80 p_out[i_out] = cur;
81 cur = 0;
82 bits_out = 0;
83 i_out++;
86 bits_out += bits_in;
87 cur <<= bits_in;
88 cur |= tmp;
91 return i_out;
94 enum dts_bitsteam_type {
95 DTS_SYNC_CORE_BE,
96 DTS_SYNC_CORE_LE,
97 DTS_SYNC_CORE_14BITS_BE,
98 DTS_SYNC_CORE_14BITS_LE,
99 DTS_SYNC_SUBSTREAM,
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;
107 else
108 if( memcmp( p_buf, "\xFE\x7F\x01\x80", 4 ) == 0 )
109 *p_bitstream_type = DTS_SYNC_CORE_LE;
110 else
111 if( memcmp( p_buf, "\x64\x58\x20\x25", 4 ) == 0 )
112 *p_bitstream_type = DTS_SYNC_SUBSTREAM;
113 else
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;
117 else
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;
121 else
122 return false;
123 return true;
126 bool vlc_dts_header_IsSync( const void *p_buf, size_t i_buf )
128 return i_buf >= 6
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
140 if( i_sfreq >= 16 )
141 return 0;
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 */
157 0, 0, 0
160 if( i_rate >= 32 )
161 return 0;
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
169 * 00: A
170 * 01: A + B (dual mono)
171 * 02: L + R (stereo)
172 * 03: (L+R) + (L-R) (sum and difference)
173 * 04: LT + RT (left and right total)
174 * 05: C + L + R
175 * 06: L + R + S
176 * 07: C + L + R + S
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;
189 switch( i_amode )
191 case 0x0:
192 i_physical_channels = AOUT_CHAN_CENTER;
193 break;
194 case 0x1:
195 i_physical_channels = AOUT_CHANS_FRONT;
196 *p_chan_mode = AOUT_CHANMODE_DUALMONO;
197 break;
198 case 0x2:
199 case 0x3:
200 case 0x4:
201 i_physical_channels = AOUT_CHANS_FRONT;
202 break;
203 case 0x5:
204 i_physical_channels = AOUT_CHANS_3_0;
205 break;
206 case 0x6:
207 i_physical_channels = AOUT_CHANS_FRONT | AOUT_CHAN_REARCENTER;
208 break;
209 case 0x7:
210 i_physical_channels = AOUT_CHANS_4_CENTER_REAR;
211 break;
212 case 0x8:
213 i_physical_channels = AOUT_CHANS_4_0;
214 break;
215 case 0x9:
216 i_physical_channels = AOUT_CHANS_5_0;
217 break;
218 case 0xA:
219 case 0xB:
220 i_physical_channels = AOUT_CHANS_6_0;
221 break;
222 case 0xC:
223 i_physical_channels = AOUT_CHANS_CENTER | AOUT_CHANS_FRONT
224 | AOUT_CHANS_REAR;
225 break;
226 case 0xD:
227 i_physical_channels = AOUT_CHANS_7_0;
228 break;
229 case 0xE:
230 case 0xF:
231 /* FIXME: AOUT_CHANS_8_0 */
232 i_physical_channels = AOUT_CHANS_7_0;
233 break;
234 default:
235 return 0;
237 if (b_lfe)
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 )
246 bs_t s;
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 );
256 else
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;
264 return VLC_SUCCESS;
267 static int dts_header_ParseCore( vlc_dts_header_t *p_header,
268 const void *p_buffer, bool b_14b )
270 bs_t s;
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 );
274 if( i_nblks < 5 )
275 return VLC_EGENERIC;
276 uint16_t i_fsize = bs_read( &s, 14 );
277 if( i_fsize < 95 )
278 return VLC_EGENERIC;
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 )
301 return VLC_EGENERIC;
303 return VLC_SUCCESS;
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 )
312 return VLC_EGENERIC;
314 if( !dts_header_IsSync( p_buffer, &bitstream_type ) )
315 return VLC_EGENERIC;
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 );
337 default:
338 vlc_assert_unreachable();