]> git.sesse.net Git - vlc/blob - modules/codec/dts_header.c
mediacodec: fix warning
[vlc] / modules / codec / dts_header.c
1 /*****************************************************************************
2  * dts_header.c: parse DTS audio headers info
3  *****************************************************************************
4  * Copyright (C) 2004-2009 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Gildas Bazin <gbazin@netcourrier.com>
8  *          Laurent Aimar
9  *
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.
14  *
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.
19  *
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  *****************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <vlc_common.h>
30 #include <vlc_bits.h>
31
32 #include "dts_header.h"
33
34 #include <assert.h>
35
36
37 static int SyncInfo16be( const uint8_t *p_buf,
38                          unsigned int *pi_audio_mode,
39                          unsigned int *pi_sample_rate,
40                          unsigned int *pi_bit_rate,
41                          unsigned int *pi_frame_length )
42 {
43     unsigned int frame_size;
44     unsigned int i_lfe;
45
46     *pi_frame_length = (p_buf[4] & 0x01) << 6 | (p_buf[5] >> 2);
47     frame_size = (p_buf[5] & 0x03) << 12 | (p_buf[6] << 4) | (p_buf[7] >> 4);
48
49     *pi_audio_mode = (p_buf[7] & 0x0f) << 2 | (p_buf[8] >> 6);
50     *pi_sample_rate = (p_buf[8] >> 2) & 0x0f;
51     *pi_bit_rate = (p_buf[8] & 0x03) << 3 | ((p_buf[9] >> 5) & 0x07);
52
53     i_lfe = (p_buf[10] >> 1) & 0x03;
54     if( i_lfe ) *pi_audio_mode |= 0x10000;
55
56     return frame_size + 1;
57 }
58
59 static void BufLeToBe( uint8_t *p_out, const uint8_t *p_in, int i_in )
60 {
61     int i;
62
63     for( i = 0; i < i_in/2; i++  )
64     {
65         p_out[i*2] = p_in[i*2+1];
66         p_out[i*2+1] = p_in[i*2];
67     }
68 }
69
70 static int Buf14To16( uint8_t *p_out, const uint8_t *p_in, int i_in, int i_le )
71 {
72     unsigned char tmp, cur = 0;
73     int bits_in, bits_out = 0;
74     int i, i_out = 0;
75
76     for( i = 0; i < i_in; i++  )
77     {
78         if( i%2 )
79         {
80             tmp = p_in[i-i_le];
81             bits_in = 8;
82         }
83         else
84         {
85             tmp = p_in[i+i_le] & 0x3F;
86             bits_in = 8 - 2;
87         }
88
89         if( bits_out < 8 )
90         {
91             int need = __MIN( 8 - bits_out, bits_in );
92             cur <<= need;
93             cur |= ( tmp >> (bits_in - need) );
94             tmp <<= (8 - bits_in + need);
95             tmp >>= (8 - bits_in + need);
96             bits_in -= need;
97             bits_out += need;
98         }
99
100         if( bits_out == 8 )
101         {
102             p_out[i_out] = cur;
103             cur = 0;
104             bits_out = 0;
105             i_out++;
106         }
107
108         bits_out += bits_in;
109         cur <<= bits_in;
110         cur |= tmp;
111     }
112
113     return i_out;
114 }
115
116 int SyncCode( const uint8_t *p_buf )
117 {
118     /* 14 bits, little endian version of the bitstream */
119     if( p_buf[0] == 0xff && p_buf[1] == 0x1f &&
120         p_buf[2] == 0x00 && p_buf[3] == 0xe8 &&
121         (p_buf[4] & 0xf0) == 0xf0 && p_buf[5] == 0x07 )
122     {
123         return VLC_SUCCESS;
124     }
125     /* 14 bits, big endian version of the bitstream */
126     else if( p_buf[0] == 0x1f && p_buf[1] == 0xff &&
127              p_buf[2] == 0xe8 && p_buf[3] == 0x00 &&
128              p_buf[4] == 0x07 && (p_buf[5] & 0xf0) == 0xf0 )
129     {
130         return VLC_SUCCESS;
131     }
132     /* 16 bits, big endian version of the bitstream */
133     else if( p_buf[0] == 0x7f && p_buf[1] == 0xfe &&
134              p_buf[2] == 0x80 && p_buf[3] == 0x01 )
135     {
136         return VLC_SUCCESS;
137     }
138     /* 16 bits, little endian version of the bitstream */
139     else if( p_buf[0] == 0xfe && p_buf[1] == 0x7f &&
140              p_buf[2] == 0x01 && p_buf[3] == 0x80 )
141     {
142         return VLC_SUCCESS;
143     }
144     /* DTS-HD */
145     else if( p_buf[0] == 0x64 && p_buf[1] ==  0x58 &&
146              p_buf[2] == 0x20 && p_buf[3] ==  0x25 )
147     {
148         return VLC_SUCCESS;
149     }
150
151     return VLC_EGENERIC;
152 }
153
154 int GetSyncInfo( const uint8_t *p_buf,
155                         bool *pb_dts_hd,
156                         unsigned int *pi_sample_rate,
157                         unsigned int *pi_bit_rate,
158                         unsigned int *pi_frame_length,
159                         unsigned int *pi_audio_mode )
160 {
161     unsigned int i_frame_size;
162
163     /* 14 bits, little endian version of the bitstream */
164     if( p_buf[0] == 0xff && p_buf[1] == 0x1f &&
165         p_buf[2] == 0x00 && p_buf[3] == 0xe8 &&
166         (p_buf[4] & 0xf0) == 0xf0 && p_buf[5] == 0x07 )
167     {
168         uint8_t conv_buf[DTS_HEADER_SIZE];
169         Buf14To16( conv_buf, p_buf, DTS_HEADER_SIZE, 1 );
170         i_frame_size = SyncInfo16be( conv_buf, pi_audio_mode, pi_sample_rate,
171                                      pi_bit_rate, pi_frame_length );
172         i_frame_size = i_frame_size * 8 / 14 * 2;
173     }
174     /* 14 bits, big endian version of the bitstream */
175     else if( p_buf[0] == 0x1f && p_buf[1] == 0xff &&
176              p_buf[2] == 0xe8 && p_buf[3] == 0x00 &&
177              p_buf[4] == 0x07 && (p_buf[5] & 0xf0) == 0xf0 )
178     {
179         uint8_t conv_buf[DTS_HEADER_SIZE];
180         Buf14To16( conv_buf, p_buf, DTS_HEADER_SIZE, 0 );
181         i_frame_size = SyncInfo16be( conv_buf, pi_audio_mode, pi_sample_rate,
182                                      pi_bit_rate, pi_frame_length );
183         i_frame_size = i_frame_size * 8 / 14 * 2;
184     }
185     /* 16 bits, big endian version of the bitstream */
186     else if( p_buf[0] == 0x7f && p_buf[1] == 0xfe &&
187              p_buf[2] == 0x80 && p_buf[3] == 0x01 )
188     {
189         i_frame_size = SyncInfo16be( p_buf, pi_audio_mode, pi_sample_rate,
190                                      pi_bit_rate, pi_frame_length );
191     }
192     /* 16 bits, little endian version of the bitstream */
193     else if( p_buf[0] == 0xfe && p_buf[1] == 0x7f &&
194              p_buf[2] == 0x01 && p_buf[3] == 0x80 )
195     {
196         uint8_t conv_buf[DTS_HEADER_SIZE];
197         BufLeToBe( conv_buf, p_buf, DTS_HEADER_SIZE );
198         i_frame_size = SyncInfo16be( conv_buf, pi_audio_mode, pi_sample_rate,
199                                      pi_bit_rate, pi_frame_length );
200     }
201     /* DTS-HD */
202     else if( p_buf[0] == 0x64 && p_buf[1] ==  0x58 &&
203                 p_buf[2] == 0x20 && p_buf[3] ==  0x25 )
204     {
205         int i_dts_hd_size;
206         bs_t s;
207         bs_init( &s, &p_buf[4], DTS_HEADER_SIZE - 4 );
208
209         bs_skip( &s, 8 + 2 );
210
211         if( bs_read1( &s ) )
212         {
213             bs_skip( &s, 12 );
214             i_dts_hd_size = bs_read( &s, 20 ) + 1;
215         }
216         else
217         {
218             bs_skip( &s, 8 );
219             i_dts_hd_size = bs_read( &s, 16 ) + 1;
220         }
221         //uint16_t s0 = bs_read( &s, 16 );
222         //uint16_t s1 = bs_read( &s, 16 );
223         //fprintf( stderr, "DTS HD=%d : %x %x\n", i_dts_hd_size, s0, s1 );
224
225         *pb_dts_hd = true;
226         /* As we ignore the stream, do not modify those variables:
227         *pi_channels = ;
228         *pi_channels_conf = ;
229         *pi_sample_rate = ;
230         *pi_bit_rate = ;
231         *pi_frame_length = ;
232         */
233         return i_dts_hd_size;
234     }
235     else
236     {
237         return VLC_EGENERIC;
238     }
239
240     *pb_dts_hd = false;
241     return i_frame_size;
242 }
243