Mercurial > mplayer.hg
annotate libmpcodecs/ad_libdca.c @ 33259:04dc3e55cd90
Increase the maximum value of the DVB timeout to 240 seconds.
Some devices may need more time for the initial tune (e.g. firmware loading).
Let the user specify higher timeout value if there is need to.
The default remains 30 seconds.
author | iive |
---|---|
date | Sun, 01 May 2011 18:07:59 +0000 |
parents | 9986a61354e6 |
children | baa7a9f7ce9e |
rev | line source |
---|---|
23821 | 1 /* |
26727 | 2 * DTS Coherent Acoustics stream decoder using libdca |
23821 | 3 * This file is partially based on dtsdec.c r9036 from FFmpeg and ad_liba52.c |
26727 | 4 * |
23821 | 5 * Copyright (C) 2007 Roberto Togni |
6 * | |
7 * This file is part of MPlayer. | |
8 * | |
9 * MPlayer is free software; you can redistribute it and/or modify | |
10 * it under the terms of the GNU General Public License as published by | |
11 * the Free Software Foundation; either version 2 of the License, or | |
12 * (at your option) any later version. | |
13 * | |
14 * MPlayer is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 * GNU General Public License for more details. | |
18 * | |
26727 | 19 * You should have received a copy of the GNU General Public License along |
20 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
23821 | 22 */ |
23 | |
24 #include <stdio.h> | |
25 #include <stdlib.h> | |
26 #include <unistd.h> | |
27 #include <assert.h> | |
28 #include "config.h" | |
29 | |
30 #include "mp_msg.h" | |
31 #include "ad_internal.h" | |
31986
9986a61354e6
Remove duplicated audio_output_channels extern variable declaration.
diego
parents:
30504
diff
changeset
|
32 #include "dec_audio.h" |
23821 | 33 |
34 #include <dts.h> | |
35 | |
30504
cc27da5d7286
Mark all ad_info_t/vd_info_t structure declarations as const.
diego
parents:
26727
diff
changeset
|
36 static const ad_info_t info = |
23821 | 37 { |
38 "DTS decoding with libdca", | |
39 "libdca", | |
40 "Roberto Togni", | |
41 "", | |
42 "" | |
43 }; | |
44 | |
45 LIBAD_EXTERN(libdca) | |
46 | |
47 #define DTSBUFFER_SIZE 18726 | |
48 #define HEADER_SIZE 14 | |
49 | |
50 #define CONVERT_LEVEL 1 | |
51 #define CONVERT_BIAS 0 | |
52 | |
53 static const char ch2flags[6] = { | |
54 DTS_MONO, | |
55 DTS_STEREO, | |
24701 | 56 DTS_3F, |
23821 | 57 DTS_2F2R, |
58 DTS_3F2R, | |
59 DTS_3F2R | DTS_LFE | |
60 }; | |
61 | |
62 static inline int16_t convert(sample_t s) | |
63 { | |
64 int i = s * 0x7fff; | |
65 | |
66 return (i > 32767) ? 32767 : ((i < -32768) ? -32768 : i); | |
67 } | |
68 | |
69 static void convert2s16_multi(sample_t *f, int16_t *s16, int flags, int ch_out) | |
70 { | |
71 int i; | |
72 | |
73 switch(flags & (DTS_CHANNEL_MASK | DTS_LFE)){ | |
74 case DTS_MONO: | |
75 if (ch_out == 1) | |
76 for(i = 0; i < 256; i++) | |
77 s16[i] = convert(f[i]); | |
78 else | |
79 for(i = 0; i < 256; i++){ | |
80 s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; | |
81 s16[5*i+4] = convert(f[i]); | |
82 } | |
83 break; | |
84 case DTS_CHANNEL: | |
85 case DTS_STEREO: | |
86 case DTS_DOLBY: | |
87 for(i = 0; i < 256; i++){ | |
88 s16[2*i] = convert(f[i]); | |
89 s16[2*i+1] = convert(f[i+256]); | |
90 } | |
91 break; | |
92 case DTS_3F: | |
93 for(i = 0; i < 256; i++){ | |
24701 | 94 s16[3*i] = convert(f[i+256]); |
95 s16[3*i+1] = convert(f[i+512]); | |
96 s16[3*i+2] = convert(f[i]); | |
23821 | 97 } |
98 break; | |
99 case DTS_2F2R: | |
100 for(i = 0; i < 256; i++){ | |
101 s16[4*i] = convert(f[i]); | |
102 s16[4*i+1] = convert(f[i+256]); | |
103 s16[4*i+2] = convert(f[i+512]); | |
104 s16[4*i+3] = convert(f[i+768]); | |
105 } | |
106 break; | |
107 case DTS_3F2R: | |
108 for(i = 0; i < 256; i++){ | |
24701 | 109 s16[5*i] = convert(f[i+256]); |
23821 | 110 s16[5*i+1] = convert(f[i+512]); |
111 s16[5*i+2] = convert(f[i+768]); | |
112 s16[5*i+3] = convert(f[i+1024]); | |
24701 | 113 s16[5*i+4] = convert(f[i]); |
23821 | 114 } |
115 break; | |
116 case DTS_MONO | DTS_LFE: | |
117 for(i = 0; i < 256; i++){ | |
118 s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; | |
24701 | 119 s16[6*i+4] = convert(f[i]); |
120 s16[6*i+5] = convert(f[i+256]); | |
23821 | 121 } |
122 break; | |
123 case DTS_CHANNEL | DTS_LFE: | |
124 case DTS_STEREO | DTS_LFE: | |
125 case DTS_DOLBY | DTS_LFE: | |
126 for(i = 0; i < 256; i++){ | |
24701 | 127 s16[6*i] = convert(f[i]); |
128 s16[6*i+1] = convert(f[i+256]); | |
23821 | 129 s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; |
24701 | 130 s16[6*i+5] = convert(f[i+512]); |
23821 | 131 } |
132 break; | |
133 case DTS_3F | DTS_LFE: | |
134 for(i = 0; i < 256; i++){ | |
135 s16[6*i] = convert(f[i+256]); | |
24701 | 136 s16[6*i+1] = convert(f[i+512]); |
23821 | 137 s16[6*i+2] = s16[6*i+3] = 0; |
24701 | 138 s16[6*i+4] = convert(f[i]); |
139 s16[6*i+5] = convert(f[i+768]); | |
23821 | 140 } |
141 break; | |
142 case DTS_2F2R | DTS_LFE: | |
143 for(i = 0; i < 256; i++){ | |
24701 | 144 s16[6*i] = convert(f[i]); |
145 s16[6*i+1] = convert(f[i+256]); | |
146 s16[6*i+2] = convert(f[i+512]); | |
147 s16[6*i+3] = convert(f[i+768]); | |
148 s16[6*i+4] = 0; | |
149 s16[6*i+5] = convert(f[1024]); | |
150 } | |
151 break; | |
152 case DTS_3F2R | DTS_LFE: | |
153 for(i = 0; i < 256; i++){ | |
23821 | 154 s16[6*i] = convert(f[i+256]); |
155 s16[6*i+1] = convert(f[i+512]); | |
156 s16[6*i+2] = convert(f[i+768]); | |
157 s16[6*i+3] = convert(f[i+1024]); | |
24701 | 158 s16[6*i+4] = convert(f[i]); |
159 s16[6*i+5] = convert(f[i+1280]); | |
23821 | 160 } |
161 break; | |
162 } | |
163 } | |
164 | |
165 static void channels_info(int flags) | |
166 { | |
167 int lfe = 0; | |
168 char lfestr[5] = ""; | |
169 | |
170 if (flags & DTS_LFE) { | |
171 lfe = 1; | |
172 strcpy(lfestr, "+lfe"); | |
173 } | |
174 mp_msg(MSGT_DECAUDIO, MSGL_V, "DTS: "); | |
175 switch(flags & DTS_CHANNEL_MASK){ | |
176 case DTS_MONO: | |
177 mp_msg(MSGT_DECAUDIO, MSGL_V, "1.%d (mono%s)", lfe, lfestr); | |
178 break; | |
179 case DTS_CHANNEL: | |
180 mp_msg(MSGT_DECAUDIO, MSGL_V, "2.%d (channel%s)", lfe, lfestr); | |
181 break; | |
182 case DTS_STEREO: | |
183 mp_msg(MSGT_DECAUDIO, MSGL_V, "2.%d (stereo%s)", lfe, lfestr); | |
184 break; | |
185 case DTS_3F: | |
24693 | 186 mp_msg(MSGT_DECAUDIO, MSGL_V, "3.%d (3f%s)", lfe, lfestr); |
23821 | 187 break; |
188 case DTS_2F2R: | |
189 mp_msg(MSGT_DECAUDIO, MSGL_V, "4.%d (2f+2r%s)", lfe, lfestr); | |
190 break; | |
191 case DTS_3F2R: | |
192 mp_msg(MSGT_DECAUDIO, MSGL_V, "5.%d (3f+2r%s)", lfe, lfestr); | |
193 break; | |
194 default: | |
195 mp_msg(MSGT_DECAUDIO, MSGL_V, "x.%d (unknown%s)", lfe, lfestr); | |
196 } | |
197 mp_msg(MSGT_DECAUDIO, MSGL_V, "\n"); | |
198 } | |
199 | |
200 static int dts_sync(sh_audio_t *sh, int *flags) | |
201 { | |
202 dts_state_t *s = sh->context; | |
203 int length; | |
204 int sample_rate; | |
205 int frame_length; | |
206 int bit_rate; | |
207 | |
208 sh->a_in_buffer_len=0; | |
209 | |
210 while(1) { | |
211 while(sh->a_in_buffer_len < HEADER_SIZE) { | |
212 int c = demux_getc(sh->ds); | |
213 | |
214 if(c < 0) | |
215 return -1; | |
216 sh->a_in_buffer[sh->a_in_buffer_len++] = c; | |
217 } | |
218 | |
219 length = dts_syncinfo(s, sh->a_in_buffer, flags, &sample_rate, | |
220 &bit_rate, &frame_length); | |
221 | |
222 if(length >= HEADER_SIZE) | |
223 break; | |
224 | |
25278
b037a816be70
Prevent from outputing mass of 'skip' log messages in verbose level.
ulion
parents:
24701
diff
changeset
|
225 // mp_msg(MSGT_DECAUDIO, MSGL_V, "skip\n"); |
23821 | 226 memmove(sh->a_in_buffer, sh->a_in_buffer+1, HEADER_SIZE-1); |
227 --sh->a_in_buffer_len; | |
228 } | |
229 | |
230 demux_read_data(sh->ds, sh->a_in_buffer + HEADER_SIZE, length - HEADER_SIZE); | |
231 | |
232 sh->samplerate = sample_rate; | |
233 sh->i_bps = bit_rate/8; | |
234 | |
235 return length; | |
236 } | |
237 | |
238 static int decode_audio(sh_audio_t *sh, unsigned char *buf, int minlen, int maxlen) | |
239 { | |
240 dts_state_t *s = sh->context; | |
241 int16_t *out_samples = (int16_t*)buf; | |
242 int flags; | |
243 level_t level; | |
244 sample_t bias; | |
245 int nblocks; | |
246 int i; | |
247 int data_size = 0; | |
248 | |
249 if(!sh->a_in_buffer_len) | |
250 if(dts_sync(sh, &flags) < 0) return -1; /* EOF */ | |
251 sh->a_in_buffer_len=0; | |
252 | |
253 flags &= ~(DTS_CHANNEL_MASK | DTS_LFE); | |
254 flags |= ch2flags[sh->channels - 1]; | |
255 | |
256 level = CONVERT_LEVEL; | |
257 bias = CONVERT_BIAS; | |
258 flags |= DTS_ADJUST_LEVEL; | |
259 if(dts_frame(s, sh->a_in_buffer, &flags, &level, bias)) { | |
260 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "dts_frame() failed\n"); | |
261 goto end; | |
262 } | |
263 | |
264 nblocks = dts_blocks_num(s); | |
265 | |
266 for(i = 0; i < nblocks; i++) { | |
267 if(dts_block(s)) { | |
268 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "dts_block() failed\n"); | |
269 goto end; | |
270 } | |
271 | |
272 convert2s16_multi(dts_samples(s), out_samples, flags, sh->channels); | |
273 | |
274 out_samples += 256 * sh->channels; | |
275 data_size += 256 * sizeof(int16_t) * sh->channels; | |
276 } | |
277 | |
278 end: | |
279 return data_size; | |
280 } | |
281 | |
282 static int preinit(sh_audio_t *sh) | |
283 { | |
284 /* 256 = samples per block, 16 = max number of blocks */ | |
285 sh->audio_out_minsize = audio_output_channels * sizeof(int16_t) * 256 * 16; | |
286 sh->audio_in_minsize = DTSBUFFER_SIZE; | |
287 sh->samplesize=2; | |
288 | |
289 return 1; | |
290 } | |
291 | |
292 static int init(sh_audio_t *sh) | |
293 { | |
294 dts_state_t *s; | |
295 int flags; | |
296 int decoded_bytes; | |
297 | |
298 s = dts_init(0); | |
299 if(s == NULL) { | |
300 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "dts_init() failed\n"); | |
301 return 0; | |
302 } | |
303 sh->context = s; | |
304 | |
305 if(dts_sync(sh, &flags) < 0) { | |
306 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "dts sync failed\n"); | |
307 dts_free(s); | |
308 return 0; | |
309 } | |
310 channels_info(flags); | |
311 | |
312 assert(audio_output_channels >= 1 && audio_output_channels <= 6); | |
313 sh->channels = audio_output_channels; | |
314 | |
315 decoded_bytes = decode_audio(sh, sh->a_buffer, 1, sh->a_buffer_size); | |
316 if(decoded_bytes > 0) | |
317 sh->a_buffer_len = decoded_bytes; | |
318 else { | |
319 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "dts decode failed on first frame (up/downmix problem?)\n"); | |
320 dts_free(s); | |
321 return 0; | |
322 } | |
323 | |
324 return 1; | |
325 } | |
326 | |
327 static void uninit(sh_audio_t *sh) | |
328 { | |
329 dts_state_t *s = sh->context; | |
330 | |
331 dts_free(s); | |
332 } | |
333 | |
334 static int control(sh_audio_t *sh,int cmd,void* arg, ...) | |
335 { | |
336 int flags; | |
337 | |
338 switch(cmd){ | |
339 case ADCTRL_RESYNC_STREAM: | |
340 dts_sync(sh, &flags); | |
341 return CONTROL_TRUE; | |
342 } | |
343 return CONTROL_UNKNOWN; | |
344 } |