Commit | Line | Data |
---|---|---|
23c99253 MN |
1 | /* |
2 | * dtsdec.c : free DTS Coherent Acoustics stream decoder. | |
3 | * Copyright (C) 2004 Benjamin Zores <ben@geexbox.org> | |
4 | * | |
b78e7197 | 5 | * This file is part of FFmpeg. |
23c99253 | 6 | * |
b78e7197 | 7 | * FFmpeg is free software; you can redistribute it and/or modify |
a708785f | 8 | * it under the terms of the GNU General Public License as published by |
bca519e0 | 9 | * the Free Software Foundation; either version 2 of the License, or |
a708785f | 10 | * (at your option) any later version. |
115329f1 | 11 | * |
b78e7197 | 12 | * FFmpeg is distributed in the hope that it will be useful, |
23c99253 | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
a708785f BZ |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU General Public License for more details. | |
115329f1 | 16 | * |
a708785f | 17 | * You should have received a copy of the GNU General Public License |
b78e7197 | 18 | * along with FFmpeg; if not, write to the Free Software |
98cc3cea | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
23c99253 MN |
20 | */ |
21 | ||
23c99253 MN |
22 | #include "avcodec.h" |
23 | #include <dts.h> | |
23c99253 MN |
24 | |
25 | #include <stdlib.h> | |
26 | #include <string.h> | |
ad730459 | 27 | |
4f26258f | 28 | #define BUFFER_SIZE 18726 |
23c99253 MN |
29 | #define HEADER_SIZE 14 |
30 | ||
31 | #ifdef LIBDTS_FIXED | |
32 | #define CONVERT_LEVEL (1 << 26) | |
33 | #define CONVERT_BIAS 0 | |
34 | #else | |
35 | #define CONVERT_LEVEL 1 | |
36 | #define CONVERT_BIAS 384 | |
37 | #endif | |
38 | ||
ac49ddc6 MR |
39 | static inline int16_t |
40 | convert(int32_t i) | |
23c99253 MN |
41 | { |
42 | #ifdef LIBDTS_FIXED | |
43 | i >>= 15; | |
44 | #else | |
45 | i -= 0x43c00000; | |
46 | #endif | |
47 | return (i > 32767) ? 32767 : ((i < -32768) ? -32768 : i); | |
48 | } | |
49 | ||
8e981daf | 50 | static void |
ac49ddc6 | 51 | convert2s16_2(sample_t * _f, int16_t * s16) |
23c99253 | 52 | { |
ac49ddc6 MR |
53 | int i; |
54 | int32_t *f = (int32_t *) _f; | |
23c99253 | 55 | |
ac49ddc6 MR |
56 | for(i = 0; i < 256; i++) { |
57 | s16[2 * i] = convert(f[i]); | |
58 | s16[2 * i + 1] = convert(f[i + 256]); | |
23c99253 MN |
59 | } |
60 | } | |
61 | ||
8e981daf | 62 | static void |
ac49ddc6 | 63 | convert2s16_4(sample_t * _f, int16_t * s16) |
23c99253 | 64 | { |
ac49ddc6 MR |
65 | int i; |
66 | int32_t *f = (int32_t *) _f; | |
23c99253 | 67 | |
ac49ddc6 MR |
68 | for(i = 0; i < 256; i++) { |
69 | s16[4 * i] = convert(f[i]); | |
70 | s16[4 * i + 1] = convert(f[i + 256]); | |
71 | s16[4 * i + 2] = convert(f[i + 512]); | |
72 | s16[4 * i + 3] = convert(f[i + 768]); | |
23c99253 MN |
73 | } |
74 | } | |
75 | ||
8e981daf | 76 | static void |
ac49ddc6 | 77 | convert2s16_5(sample_t * _f, int16_t * s16) |
23c99253 | 78 | { |
ac49ddc6 MR |
79 | int i; |
80 | int32_t *f = (int32_t *) _f; | |
23c99253 | 81 | |
ac49ddc6 MR |
82 | for(i = 0; i < 256; i++) { |
83 | s16[5 * i] = convert(f[i]); | |
84 | s16[5 * i + 1] = convert(f[i + 256]); | |
85 | s16[5 * i + 2] = convert(f[i + 512]); | |
86 | s16[5 * i + 3] = convert(f[i + 768]); | |
87 | s16[5 * i + 4] = convert(f[i + 1024]); | |
23c99253 MN |
88 | } |
89 | } | |
90 | ||
91 | static void | |
ac49ddc6 | 92 | convert2s16_multi(sample_t * _f, int16_t * s16, int flags) |
23c99253 | 93 | { |
ac49ddc6 MR |
94 | int i; |
95 | int32_t *f = (int32_t *) _f; | |
23c99253 | 96 | |
ac49ddc6 | 97 | switch (flags) { |
23c99253 | 98 | case DTS_MONO: |
ac49ddc6 MR |
99 | for(i = 0; i < 256; i++) { |
100 | s16[5 * i] = s16[5 * i + 1] = s16[5 * i + 2] = s16[5 * i + 3] = | |
101 | 0; | |
102 | s16[5 * i + 4] = convert(f[i]); | |
23c99253 | 103 | } |
ac49ddc6 | 104 | break; |
23c99253 MN |
105 | case DTS_CHANNEL: |
106 | case DTS_STEREO: | |
107 | case DTS_DOLBY: | |
ac49ddc6 MR |
108 | convert2s16_2(_f, s16); |
109 | break; | |
23c99253 | 110 | case DTS_3F: |
ac49ddc6 MR |
111 | for(i = 0; i < 256; i++) { |
112 | s16[5 * i] = convert(f[i]); | |
113 | s16[5 * i + 1] = convert(f[i + 512]); | |
114 | s16[5 * i + 2] = s16[5 * i + 3] = 0; | |
115 | s16[5 * i + 4] = convert(f[i + 256]); | |
23c99253 | 116 | } |
ac49ddc6 | 117 | break; |
23c99253 | 118 | case DTS_2F2R: |
ac49ddc6 MR |
119 | convert2s16_4(_f, s16); |
120 | break; | |
23c99253 | 121 | case DTS_3F2R: |
ac49ddc6 MR |
122 | convert2s16_5(_f, s16); |
123 | break; | |
23c99253 | 124 | case DTS_MONO | DTS_LFE: |
ac49ddc6 MR |
125 | for(i = 0; i < 256; i++) { |
126 | s16[6 * i] = s16[6 * i + 1] = s16[6 * i + 2] = s16[6 * i + 3] = | |
127 | 0; | |
128 | s16[6 * i + 4] = convert(f[i + 256]); | |
129 | s16[6 * i + 5] = convert(f[i]); | |
23c99253 | 130 | } |
ac49ddc6 | 131 | break; |
23c99253 MN |
132 | case DTS_CHANNEL | DTS_LFE: |
133 | case DTS_STEREO | DTS_LFE: | |
134 | case DTS_DOLBY | DTS_LFE: | |
ac49ddc6 MR |
135 | for(i = 0; i < 256; i++) { |
136 | s16[6 * i] = convert(f[i + 256]); | |
137 | s16[6 * i + 1] = convert(f[i + 512]); | |
138 | s16[6 * i + 2] = s16[6 * i + 3] = s16[6 * i + 4] = 0; | |
139 | s16[6 * i + 5] = convert(f[i]); | |
23c99253 | 140 | } |
ac49ddc6 | 141 | break; |
23c99253 | 142 | case DTS_3F | DTS_LFE: |
ac49ddc6 MR |
143 | for(i = 0; i < 256; i++) { |
144 | s16[6 * i] = convert(f[i + 256]); | |
145 | s16[6 * i + 1] = convert(f[i + 768]); | |
146 | s16[6 * i + 2] = s16[6 * i + 3] = 0; | |
147 | s16[6 * i + 4] = convert(f[i + 512]); | |
148 | s16[6 * i + 5] = convert(f[i]); | |
23c99253 | 149 | } |
ac49ddc6 | 150 | break; |
23c99253 | 151 | case DTS_2F2R | DTS_LFE: |
ac49ddc6 MR |
152 | for(i = 0; i < 256; i++) { |
153 | s16[6 * i] = convert(f[i + 256]); | |
154 | s16[6 * i + 1] = convert(f[i + 512]); | |
155 | s16[6 * i + 2] = convert(f[i + 768]); | |
156 | s16[6 * i + 3] = convert(f[i + 1024]); | |
157 | s16[6 * i + 4] = 0; | |
158 | s16[6 * i + 5] = convert(f[i]); | |
23c99253 | 159 | } |
ac49ddc6 | 160 | break; |
23c99253 | 161 | case DTS_3F2R | DTS_LFE: |
ac49ddc6 MR |
162 | for(i = 0; i < 256; i++) { |
163 | s16[6 * i] = convert(f[i + 256]); | |
164 | s16[6 * i + 1] = convert(f[i + 768]); | |
165 | s16[6 * i + 2] = convert(f[i + 1024]); | |
166 | s16[6 * i + 3] = convert(f[i + 1280]); | |
167 | s16[6 * i + 4] = convert(f[i + 512]); | |
168 | s16[6 * i + 5] = convert(f[i]); | |
23c99253 | 169 | } |
ac49ddc6 | 170 | break; |
23c99253 MN |
171 | } |
172 | } | |
173 | ||
174 | static int | |
ac49ddc6 | 175 | channels_multi(int flags) |
23c99253 | 176 | { |
ac49ddc6 MR |
177 | if(flags & DTS_LFE) |
178 | return 6; | |
179 | else if(flags & 1) /* center channel */ | |
180 | return 5; | |
181 | else if((flags & DTS_CHANNEL_MASK) == DTS_2F2R) | |
182 | return 4; | |
183 | else | |
184 | return 2; | |
23c99253 MN |
185 | } |
186 | ||
187 | static int | |
ac49ddc6 MR |
188 | dts_decode_frame(AVCodecContext * avctx, void *data, int *data_size, |
189 | uint8_t * buff, int buff_size) | |
23c99253 | 190 | { |
ac49ddc6 MR |
191 | uint8_t *start = buff; |
192 | uint8_t *end = buff + buff_size; | |
193 | static uint8_t buf[BUFFER_SIZE]; | |
194 | static uint8_t *bufptr = buf; | |
195 | static uint8_t *bufpos = buf + HEADER_SIZE; | |
196 | int16_t *out_samples = data; | |
197 | static int sample_rate; | |
198 | static int frame_length; | |
199 | static int flags; | |
200 | int bit_rate; | |
201 | int len; | |
202 | dts_state_t *state = avctx->priv_data; | |
8af23633 MR |
203 | level_t level; |
204 | sample_t bias; | |
205 | int i; | |
23c99253 | 206 | |
ac49ddc6 | 207 | *data_size = 0; |
0fd847a1 | 208 | |
ac49ddc6 | 209 | while(1) { |
8af23633 MR |
210 | int length; |
211 | ||
ac49ddc6 MR |
212 | len = end - start; |
213 | if(!len) | |
214 | break; | |
215 | if(len > bufpos - bufptr) | |
216 | len = bufpos - bufptr; | |
217 | memcpy(bufptr, start, len); | |
218 | bufptr += len; | |
219 | start += len; | |
220 | if(bufptr != bufpos) | |
221 | return start - buff; | |
222 | if(bufpos != buf + HEADER_SIZE) | |
223 | break; | |
4f26258f | 224 | |
8af23633 MR |
225 | length = dts_syncinfo(state, buf, &flags, &sample_rate, &bit_rate, |
226 | &frame_length); | |
227 | if(!length) { | |
228 | av_log(NULL, AV_LOG_INFO, "skip\n"); | |
229 | for(bufptr = buf; bufptr < buf + HEADER_SIZE - 1; bufptr++) | |
230 | bufptr[0] = bufptr[1]; | |
231 | continue; | |
ac49ddc6 | 232 | } |
8af23633 MR |
233 | bufpos = buf + length; |
234 | } | |
235 | ||
236 | flags = 2; /* ???????????? */ | |
237 | level = CONVERT_LEVEL; | |
238 | bias = CONVERT_BIAS; | |
239 | ||
240 | flags |= DTS_ADJUST_LEVEL; | |
241 | if(dts_frame(state, buf, &flags, &level, bias)) { | |
242 | av_log(avctx, AV_LOG_ERROR, "dts_frame() failed\n"); | |
243 | goto end; | |
4f26258f UU |
244 | } |
245 | ||
8af23633 MR |
246 | avctx->sample_rate = sample_rate; |
247 | avctx->channels = channels_multi(flags); | |
248 | avctx->bit_rate = bit_rate; | |
249 | ||
250 | for(i = 0; i < dts_blocks_num(state); i++) { | |
251 | int chans; | |
252 | ||
253 | if(dts_block(state)) { | |
254 | av_log(avctx, AV_LOG_ERROR, "dts_block() failed\n"); | |
255 | goto end; | |
ac49ddc6 | 256 | } |
8af23633 MR |
257 | |
258 | chans = channels_multi(flags); | |
259 | convert2s16_multi(dts_samples(state), out_samples, | |
260 | flags & (DTS_CHANNEL_MASK | DTS_LFE)); | |
261 | ||
262 | out_samples += 256 * chans; | |
263 | *data_size += 256 * sizeof(int16_t) * chans; | |
ac49ddc6 | 264 | } |
23c99253 | 265 | |
8af23633 MR |
266 | end: |
267 | bufptr = buf; | |
268 | bufpos = buf + HEADER_SIZE; | |
ac49ddc6 | 269 | return start - buff; |
23c99253 MN |
270 | } |
271 | ||
272 | static int | |
ac49ddc6 | 273 | dts_decode_init(AVCodecContext * avctx) |
23c99253 | 274 | { |
ac49ddc6 MR |
275 | avctx->priv_data = dts_init(0); |
276 | if(avctx->priv_data == NULL) | |
277 | return -1; | |
23c99253 | 278 | |
ac49ddc6 | 279 | return 0; |
23c99253 MN |
280 | } |
281 | ||
282 | static int | |
ac49ddc6 | 283 | dts_decode_end(AVCodecContext * s) |
23c99253 | 284 | { |
ac49ddc6 | 285 | return 0; |
23c99253 MN |
286 | } |
287 | ||
288 | AVCodec dts_decoder = { | |
ac49ddc6 MR |
289 | "dts", |
290 | CODEC_TYPE_AUDIO, | |
291 | CODEC_ID_DTS, | |
292 | sizeof(dts_state_t *), | |
293 | dts_decode_init, | |
294 | NULL, | |
295 | dts_decode_end, | |
296 | dts_decode_frame, | |
23c99253 | 297 | }; |