Mercurial > mplayer.hg
annotate libmpcodecs/ad_libdca.c @ 36963:e539d330c7be
Remove unnecessary bounds checks in Win32 GUI.
The checks that the rendered potmeter button
doesn't exceed the bounds is not necessary as
the item value is already limited within the
range of 0 to 100.
Patch by Hans-Dieter Kosch, hdkosch kabelbw de.
author | ib |
---|---|
date | Mon, 24 Mar 2014 12:52:01 +0000 |
parents | baa7a9f7ce9e |
children |
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 |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
34 #include <dca.h> |
23821 | 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] = { | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
54 DCA_MONO, |
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
55 DCA_STEREO, |
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
56 DCA_3F, |
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
57 DCA_2F2R, |
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
58 DCA_3F2R, |
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
59 DCA_3F2R | DCA_LFE |
23821 | 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 | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
73 switch(flags & (DCA_CHANNEL_MASK | DCA_LFE)){ |
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
74 case DCA_MONO: |
23821 | 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; | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
84 case DCA_CHANNEL: |
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
85 case DCA_STEREO: |
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
86 case DCA_DOLBY: |
23821 | 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; | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
92 case DCA_3F: |
23821 | 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; | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
99 case DCA_2F2R: |
23821 | 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; | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
107 case DCA_3F2R: |
23821 | 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; | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
116 case DCA_MONO | DCA_LFE: |
23821 | 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; | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
123 case DCA_CHANNEL | DCA_LFE: |
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
124 case DCA_STEREO | DCA_LFE: |
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
125 case DCA_DOLBY | DCA_LFE: |
23821 | 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; | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
133 case DCA_3F | DCA_LFE: |
23821 | 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; | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
142 case DCA_2F2R | DCA_LFE: |
23821 | 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; | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
152 case DCA_3F2R | DCA_LFE: |
24701 | 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 | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
170 if (flags & DCA_LFE) { |
23821 | 171 lfe = 1; |
172 strcpy(lfestr, "+lfe"); | |
173 } | |
174 mp_msg(MSGT_DECAUDIO, MSGL_V, "DTS: "); | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
175 switch(flags & DCA_CHANNEL_MASK){ |
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
176 case DCA_MONO: |
23821 | 177 mp_msg(MSGT_DECAUDIO, MSGL_V, "1.%d (mono%s)", lfe, lfestr); |
178 break; | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
179 case DCA_CHANNEL: |
23821 | 180 mp_msg(MSGT_DECAUDIO, MSGL_V, "2.%d (channel%s)", lfe, lfestr); |
181 break; | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
182 case DCA_STEREO: |
23821 | 183 mp_msg(MSGT_DECAUDIO, MSGL_V, "2.%d (stereo%s)", lfe, lfestr); |
184 break; | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
185 case DCA_3F: |
24693 | 186 mp_msg(MSGT_DECAUDIO, MSGL_V, "3.%d (3f%s)", lfe, lfestr); |
23821 | 187 break; |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
188 case DCA_2F2R: |
23821 | 189 mp_msg(MSGT_DECAUDIO, MSGL_V, "4.%d (2f+2r%s)", lfe, lfestr); |
190 break; | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
191 case DCA_3F2R: |
23821 | 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 { | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
202 dca_state_t *s = sh->context; |
23821 | 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 | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
219 length = dca_syncinfo(s, sh->a_in_buffer, flags, &sample_rate, |
23821 | 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 { | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
240 dca_state_t *s = sh->context; |
23821 | 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 | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
253 flags &= ~(DCA_CHANNEL_MASK | DCA_LFE); |
23821 | 254 flags |= ch2flags[sh->channels - 1]; |
255 | |
256 level = CONVERT_LEVEL; | |
257 bias = CONVERT_BIAS; | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
258 flags |= DCA_ADJUST_LEVEL; |
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
259 if(dca_frame(s, sh->a_in_buffer, &flags, &level, bias)) { |
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
260 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "dca_frame() failed\n"); |
23821 | 261 goto end; |
262 } | |
263 | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
264 nblocks = dca_blocks_num(s); |
23821 | 265 |
266 for(i = 0; i < nblocks; i++) { | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
267 if(dca_block(s)) { |
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
268 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "dca_block() failed\n"); |
23821 | 269 goto end; |
270 } | |
271 | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
272 convert2s16_multi(dca_samples(s), out_samples, flags, sh->channels); |
23821 | 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 { | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
294 dca_state_t *s; |
23821 | 295 int flags; |
296 int decoded_bytes; | |
297 | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
298 s = dca_init(0); |
23821 | 299 if(s == NULL) { |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
300 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "dca_init() failed\n"); |
23821 | 301 return 0; |
302 } | |
303 sh->context = s; | |
304 | |
305 if(dts_sync(sh, &flags) < 0) { | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
306 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "dca sync failed\n"); |
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
307 dca_free(s); |
23821 | 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"); | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
320 dca_free(s); |
23821 | 321 return 0; |
322 } | |
323 | |
324 return 1; | |
325 } | |
326 | |
327 static void uninit(sh_audio_t *sh) | |
328 { | |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
329 dca_state_t *s = sh->context; |
23821 | 330 |
36606
baa7a9f7ce9e
ad_libdca: support current libdca that does not provide a dts.h header.
reimar
parents:
31986
diff
changeset
|
331 dca_free(s); |
23821 | 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 } |