Update translations from 2.2.x branch
[vlc.git] / modules / packetizer / a52.h
blobc46a0f2bb9ed86f418c2d2d6044b7be999acd8a7
1 /*****************************************************************************
2 * a52.h
3 *****************************************************************************
4 * Copyright (C) 2001-2016 Laurent Aimar
5 * $Id$
7 * Authors: Stéphane Borel <stef@via.ecp.fr>
8 * Christophe Massiot <massiot@via.ecp.fr>
9 * Gildas Bazin <gbazin@videolan.org>
10 * Laurent Aimar <fenrir@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 #ifndef VLC_A52_H_
29 #define VLC_A52_H_
31 #include <vlc_bits.h>
33 /**
34 * Minimum AC3 header size that vlc_a52_header_Parse needs.
36 #define VLC_A52_HEADER_SIZE (8)
38 /**
39 * AC3 header information.
41 typedef struct
43 bool b_eac3;
45 unsigned int i_channels;
46 unsigned int i_channels_conf;
47 unsigned int i_chan_mode;
48 unsigned int i_rate;
49 unsigned int i_bitrate;
51 unsigned int i_size;
52 unsigned int i_samples;
54 union {
55 struct {
56 enum {
57 EAC3_STRMTYP_INDEPENDENT = 0,
58 EAC3_STRMTYP_DEPENDENT = 1,
59 EAC3_STRMTYP_AC3_CONVERT = 2,
60 EAC3_STRMTYP_RESERVED,
61 } strmtyp;
62 uint8_t i_substreamid;
63 } eac3;
65 uint8_t i_blocks_per_sync_frame;
66 } vlc_a52_header_t;
68 /**
69 * It parse AC3 sync info.
71 * cf. AC3 spec
73 static inline int vlc_a52_header_ParseAc3( vlc_a52_header_t *p_header,
74 const uint8_t *p_buf,
75 const uint32_t *p_acmod,
76 const unsigned *pi_fscod_samplerates )
78 /* cf. Table 5.18 Frame Size Code Table */
79 static const uint16_t ppi_frmsizcod_fscod_sizes[][3] = {
80 /* 32K, 44.1K, 48K */
81 { 96, 69, 64 },
82 { 96, 70, 64 },
83 { 120, 87, 80 },
84 { 120, 88, 80 },
85 { 144, 104, 96 },
86 { 144, 105, 96 },
87 { 168, 121, 112 },
88 { 168, 122, 112 },
89 { 192, 139, 128 },
90 { 192, 140, 128 },
91 { 240, 174, 160 },
92 { 240, 175, 160 },
93 { 288, 208, 192 },
94 { 288, 209, 192 },
95 { 336, 243, 224 },
96 { 336, 244, 224 },
97 { 384, 278, 256 },
98 { 384, 279, 256 },
99 { 480, 348, 320 },
100 { 480, 349, 320 },
101 { 576, 417, 384 },
102 { 576, 418, 384 },
103 { 672, 487, 448 },
104 { 672, 488, 448 },
105 { 768, 557, 512 },
106 { 768, 558, 512 },
107 { 960, 696, 640 },
108 { 960, 697, 640 },
109 { 1152, 835, 768 },
110 { 1152, 836, 768 },
111 { 1344, 975, 896 },
112 { 1344, 976, 896 },
113 { 1536, 1114, 1024 },
114 { 1536, 1115, 1024 },
115 { 1728, 1253, 1152 },
116 { 1728, 1254, 1152 },
117 { 1920, 1393, 1280 },
118 { 1920, 1394, 1280 }
120 static const uint16_t pi_frmsizcod_bitrates[] = {
121 32, 40, 48, 56,
122 64, 80, 96, 112,
123 128, 160, 192, 224,
124 256, 320, 384, 448,
125 512, 576, 640
128 bs_t s;
129 bs_init( &s, (void*)p_buf, VLC_A52_HEADER_SIZE );
130 bs_skip( &s, 32 ); /* start code + CRC */
132 /* cf. 5.3.2 */
133 const uint8_t i_fscod = bs_read( &s, 2 );
134 if( i_fscod == 3 )
135 return VLC_EGENERIC;
136 const uint8_t i_frmsizcod = bs_read( &s, 6 );
137 if( i_frmsizcod >= 38 )
138 return VLC_EGENERIC;
139 const uint8_t i_bsid = bs_read( &s, 5 );
140 bs_skip( &s, 3 ); /* i_bsmod */
141 const uint8_t i_acmod = bs_read( &s, 3 );
142 if( ( i_acmod & 0x1 ) && ( i_acmod != 0x1 ) )
144 /* if 3 front channels */
145 bs_skip( &s, 2 ); /* i_cmixlev */
147 if( i_acmod & 0x4 )
149 /* if a surround channel exists */
150 bs_skip( &s, 2 ); /* i_surmixlev */
152 /* if in 2/0 mode */
153 const uint8_t i_dsurmod = i_acmod == 0x2 ? bs_read( &s, 2 ) : 0;
154 const uint8_t i_lfeon = bs_read( &s, 1 );
156 p_header->i_channels_conf = p_acmod[i_acmod];
157 p_header->i_chan_mode = 0;
158 if( i_dsurmod == 2 )
159 p_header->i_chan_mode |= AOUT_CHANMODE_DOLBYSTEREO;
160 if( i_acmod == 0 )
161 p_header->i_chan_mode |= AOUT_CHANMODE_DUALMONO;
163 if( i_lfeon )
164 p_header->i_channels_conf |= AOUT_CHAN_LFE;
166 p_header->i_channels = popcount(p_header->i_channels_conf);
168 const unsigned i_rate_shift = VLC_CLIP(i_bsid, 8, 11) - 8;
169 p_header->i_bitrate = (pi_frmsizcod_bitrates[i_frmsizcod >> 1] * 1000)
170 >> i_rate_shift;
171 p_header->i_rate = pi_fscod_samplerates[i_fscod] >> i_rate_shift;
173 p_header->i_size = ppi_frmsizcod_fscod_sizes[i_frmsizcod][2 - i_fscod] * 2;
174 p_header->i_blocks_per_sync_frame = 6;
175 p_header->i_samples = p_header->i_blocks_per_sync_frame * 256;
177 p_header->b_eac3 = false;
178 return VLC_SUCCESS;
182 * It parse E-AC3 sync info
184 static inline int vlc_a52_header_ParseEac3( vlc_a52_header_t *p_header,
185 const uint8_t *p_buf,
186 const uint32_t *p_acmod,
187 const unsigned *pi_fscod_samplerates )
189 bs_t s;
190 bs_init( &s, (void*)p_buf, VLC_A52_HEADER_SIZE );
191 bs_skip( &s, 16 ); /* start code */
192 p_header->eac3.strmtyp = bs_read( &s, 2 ); /* Stream Type */
193 p_header->eac3.i_substreamid = bs_read( &s, 3 );/* Substream Identification */
195 const uint16_t i_frmsiz = bs_read( &s, 11 );
196 if( i_frmsiz < 2 )
197 return VLC_EGENERIC;
198 p_header->i_size = 2 * (i_frmsiz + 1 );
200 const uint8_t i_fscod = bs_read( &s, 2 );
201 if( i_fscod == 0x03 )
203 const uint8_t i_fscod2 = bs_read( &s, 2 );
204 if( i_fscod2 == 0x03 )
205 return VLC_EGENERIC;
206 p_header->i_rate = pi_fscod_samplerates[i_fscod2] / 2;
207 p_header->i_blocks_per_sync_frame = 6;
209 else
211 static const int pi_numblkscod [4] = { 1, 2, 3, 6 };
213 p_header->i_rate = pi_fscod_samplerates[i_fscod];
214 p_header->i_blocks_per_sync_frame = pi_numblkscod[bs_read( &s, 2 )];
217 const unsigned i_acmod = bs_read( &s, 3 );
218 const unsigned i_lfeon = bs_read1( &s );
220 p_header->i_channels_conf = p_acmod[i_acmod];
221 p_header->i_chan_mode = 0;
222 if( i_acmod == 0 )
223 p_header->i_chan_mode |= AOUT_CHANMODE_DUALMONO;
224 if( i_lfeon )
225 p_header->i_channels_conf |= AOUT_CHAN_LFE;
226 p_header->i_channels = popcount( p_header->i_channels_conf );
227 p_header->i_bitrate = 8 * p_header->i_size * p_header->i_rate
228 / (p_header->i_blocks_per_sync_frame * 256);
229 p_header->i_samples = p_header->i_blocks_per_sync_frame * 256;
231 p_header->b_eac3 = true;
232 return VLC_SUCCESS;
236 * It will parse the header AC3 frame and fill vlc_a52_header_t* if
237 * it is valid or return VLC_EGENERIC.
239 * XXX It will only recognize big endian bitstream ie starting with 0x0b, 0x77
241 static inline int vlc_a52_header_Parse( vlc_a52_header_t *p_header,
242 const uint8_t *p_buffer, int i_buffer )
244 static const uint32_t p_acmod[8] = {
245 AOUT_CHANS_2_0,
246 AOUT_CHAN_CENTER,
247 AOUT_CHANS_2_0,
248 AOUT_CHANS_3_0,
249 AOUT_CHANS_FRONT | AOUT_CHAN_REARCENTER, /* 2F1R */
250 AOUT_CHANS_FRONT | AOUT_CHANS_CENTER, /* 3F1R */
251 AOUT_CHANS_4_0,
252 AOUT_CHANS_5_0,
254 static const unsigned pi_fscod_samplerates[] = {
255 48000, 44100, 32000
258 if( i_buffer < VLC_A52_HEADER_SIZE )
259 return VLC_EGENERIC;
261 /* Check synword */
262 if( p_buffer[0] != 0x0b || p_buffer[1] != 0x77 )
263 return VLC_EGENERIC;
265 /* Check bsid */
266 const int bsid = p_buffer[5] >> 3;
268 /* cf. Annex E 2.3.1.6 of AC3 spec */
269 if( bsid <= 10 )
270 return vlc_a52_header_ParseAc3( p_header, p_buffer,
271 p_acmod, pi_fscod_samplerates );
272 else if( bsid <= 16 )
273 return vlc_a52_header_ParseEac3( p_header, p_buffer,
274 p_acmod, pi_fscod_samplerates );
275 else
276 return VLC_EGENERIC;
279 #endif