Mercurial > libavcodec.hg
annotate dtsdec.c @ 4952:1900e2eaecda libavcodec
Add another tmpbias variable, as bias' value will be used later
| author | ramiro |
|---|---|
| date | Wed, 09 May 2007 21:56:22 +0000 |
| parents | 8f47dc8782f9 |
| children | 03aa103464d4 |
| rev | line source |
|---|---|
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
1 /* |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
2 * dtsdec.c : free DTS Coherent Acoustics stream decoder. |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
3 * Copyright (C) 2004 Benjamin Zores <ben@geexbox.org> |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
4 * |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3267
diff
changeset
|
5 * This file is part of FFmpeg. |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
6 * |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3267
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or modify |
| 2126 | 8 * it under the terms of the GNU General Public License as published by |
| 3965 | 9 * the Free Software Foundation; either version 2 of the License, or |
| 2126 | 10 * (at your option) any later version. |
| 2967 | 11 * |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3267
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 2126 | 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 * GNU General Public License for more details. | |
| 2967 | 16 * |
| 2126 | 17 * You should have received a copy of the GNU General Public License |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3267
diff
changeset
|
18 * along with FFmpeg; if not, write to the Free Software |
| 4385 | 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
20 */ |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
21 |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
22 #include "avcodec.h" |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
23 #include <dts.h> |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
24 |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
25 #include <stdlib.h> |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
26 #include <string.h> |
| 2186 | 27 |
|
3267
8072ed8993f6
dtsdec.c copies one input packet at a time to a (static) buffer of size
rtognimp
parents:
2979
diff
changeset
|
28 #define BUFFER_SIZE 18726 |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
29 #define HEADER_SIZE 14 |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
30 |
| 4482 | 31 #define CONVERT_LEVEL 1 |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
32 #define CONVERT_BIAS 0 |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
33 |
| 4481 | 34 typedef struct DTSContext { |
| 35 dts_state_t *state; | |
| 36 uint8_t buf[BUFFER_SIZE]; | |
| 37 uint8_t *bufptr; | |
| 38 uint8_t *bufpos; | |
| 39 } DTSContext; | |
| 40 | |
| 4478 | 41 static inline int16_t |
| 4482 | 42 convert(sample_t s) |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
43 { |
| 4482 | 44 return s * 0x7fff; |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
45 } |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
46 |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
47 static void |
| 4482 | 48 convert2s16_multi(sample_t *f, int16_t *s16, int flags) |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
49 { |
| 4478 | 50 int i; |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
51 |
| 4482 | 52 switch(flags & (DTS_CHANNEL_MASK | DTS_LFE)){ |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
53 case DTS_MONO: |
| 4482 | 54 for(i = 0; i < 256; i++){ |
| 55 s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; | |
| 56 s16[5*i+4] = convert(f[i]); | |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
57 } |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
58 case DTS_CHANNEL: |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
59 case DTS_STEREO: |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
60 case DTS_DOLBY: |
| 4482 | 61 for(i = 0; i < 256; i++){ |
| 62 s16[2*i] = convert(f[i]); | |
| 63 s16[2*i+1] = convert(f[i+256]); | |
| 64 } | |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
65 case DTS_3F: |
| 4482 | 66 for(i = 0; i < 256; i++){ |
| 67 s16[5*i] = convert(f[i+256]); | |
| 68 s16[5*i+1] = convert(f[i+512]); | |
| 69 s16[5*i+2] = s16[5*i+3] = 0; | |
| 70 s16[5*i+4] = convert(f[i]); | |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
71 } |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
72 case DTS_2F2R: |
| 4482 | 73 for(i = 0; i < 256; i++){ |
| 74 s16[4*i] = convert(f[i]); | |
| 75 s16[4*i+1] = convert(f[i+256]); | |
| 76 s16[4*i+2] = convert(f[i+512]); | |
| 77 s16[4*i+3] = convert(f[i+768]); | |
| 78 } | |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
79 case DTS_3F2R: |
| 4482 | 80 for(i = 0; i < 256; i++){ |
| 81 s16[5*i] = convert(f[i+256]); | |
| 82 s16[5*i+1] = convert(f[i+512]); | |
| 83 s16[5*i+2] = convert(f[i+768]); | |
| 84 s16[5*i+3] = convert(f[i+1024]); | |
| 85 s16[5*i+4] = convert(f[i]); | |
| 86 } | |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
87 case DTS_MONO | DTS_LFE: |
| 4482 | 88 for(i = 0; i < 256; i++){ |
| 89 s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; | |
| 90 s16[6*i+4] = convert(f[i]); | |
| 91 s16[6*i+5] = convert(f[i+256]); | |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
92 } |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
93 case DTS_CHANNEL | DTS_LFE: |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
94 case DTS_STEREO | DTS_LFE: |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
95 case DTS_DOLBY | DTS_LFE: |
| 4482 | 96 for(i = 0; i < 256; i++){ |
| 97 s16[6*i] = convert(f[i]); | |
| 98 s16[6*i+1] = convert(f[i+256]); | |
| 99 s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; | |
| 100 s16[6*i+5] = convert(f[i+512]); | |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
101 } |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
102 case DTS_3F | DTS_LFE: |
| 4482 | 103 for(i = 0; i < 256; i++){ |
| 104 s16[6*i] = convert(f[i+256]); | |
| 105 s16[6*i+1] = convert(f[i+512]); | |
| 106 s16[6*i+2] = s16[6*i+3] = 0; | |
| 107 s16[6*i+4] = convert(f[i]); | |
| 108 s16[6*i+5] = convert(f[i+768]); | |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
109 } |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
110 case DTS_2F2R | DTS_LFE: |
| 4482 | 111 for(i = 0; i < 256; i++){ |
| 112 s16[6*i] = convert(f[i]); | |
| 113 s16[6*i+1] = convert(f[i+256]); | |
| 114 s16[6*i+2] = convert(f[i+512]); | |
| 115 s16[6*i+3] = convert(f[i+768]); | |
| 116 s16[6*i+4] = 0; | |
| 117 s16[6*i+5] = convert(f[i+1024]); | |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
118 } |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
119 case DTS_3F2R | DTS_LFE: |
| 4482 | 120 for(i = 0; i < 256; i++){ |
| 121 s16[6*i] = convert(f[i+256]); | |
| 122 s16[6*i+1] = convert(f[i+512]); | |
| 123 s16[6*i+2] = convert(f[i+768]); | |
| 124 s16[6*i+3] = convert(f[i+1024]); | |
| 125 s16[6*i+4] = convert(f[i]); | |
| 126 s16[6*i+5] = convert(f[i+1280]); | |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
127 } |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
128 } |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
129 } |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
130 |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
131 static int |
| 4478 | 132 channels_multi(int flags) |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
133 { |
| 4482 | 134 switch(flags & (DTS_CHANNEL_MASK | DTS_LFE)){ |
| 135 case DTS_CHANNEL: | |
| 136 case DTS_STEREO: | |
| 137 case DTS_DOLBY: | |
| 138 return 2; | |
| 139 case DTS_2F2R: | |
| 140 return 4; | |
| 141 case DTS_MONO: | |
| 142 case DTS_3F: | |
| 143 case DTS_3F2R: | |
| 4478 | 144 return 5; |
| 4482 | 145 case DTS_MONO | DTS_LFE: |
| 146 case DTS_CHANNEL | DTS_LFE: | |
| 147 case DTS_STEREO | DTS_LFE: | |
| 148 case DTS_DOLBY | DTS_LFE: | |
| 149 case DTS_3F | DTS_LFE: | |
| 150 case DTS_2F2R | DTS_LFE: | |
| 151 case DTS_3F2R | DTS_LFE: | |
| 152 return 6; | |
| 153 } | |
| 154 | |
| 155 return -1; | |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
156 } |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
157 |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
158 static int |
| 4478 | 159 dts_decode_frame(AVCodecContext * avctx, void *data, int *data_size, |
| 160 uint8_t * buff, int buff_size) | |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
161 { |
| 4481 | 162 DTSContext *s = avctx->priv_data; |
| 4478 | 163 uint8_t *start = buff; |
| 164 uint8_t *end = buff + buff_size; | |
| 165 int16_t *out_samples = data; | |
| 4481 | 166 int sample_rate; |
| 167 int frame_length; | |
| 168 int flags; | |
| 4478 | 169 int bit_rate; |
| 170 int len; | |
| 4479 | 171 level_t level; |
| 172 sample_t bias; | |
| 4482 | 173 int nblocks; |
| 4479 | 174 int i; |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
175 |
| 4478 | 176 *data_size = 0; |
| 2222 | 177 |
| 4478 | 178 while(1) { |
| 4479 | 179 int length; |
| 180 | |
| 4478 | 181 len = end - start; |
| 182 if(!len) | |
| 183 break; | |
| 4481 | 184 if(len > s->bufpos - s->bufptr) |
| 185 len = s->bufpos - s->bufptr; | |
| 186 memcpy(s->bufptr, start, len); | |
| 187 s->bufptr += len; | |
| 4478 | 188 start += len; |
| 4481 | 189 if(s->bufptr != s->bufpos) |
| 4478 | 190 return start - buff; |
| 4481 | 191 if(s->bufpos != s->buf + HEADER_SIZE) |
| 4478 | 192 break; |
|
3267
8072ed8993f6
dtsdec.c copies one input packet at a time to a (static) buffer of size
rtognimp
parents:
2979
diff
changeset
|
193 |
| 4481 | 194 length = dts_syncinfo(s->state, s->buf, &flags, &sample_rate, |
| 195 &bit_rate, &frame_length); | |
| 4479 | 196 if(!length) { |
| 197 av_log(NULL, AV_LOG_INFO, "skip\n"); | |
| 4481 | 198 for(s->bufptr = s->buf; s->bufptr < s->buf + HEADER_SIZE - 1; s->bufptr++) |
| 199 s->bufptr[0] = s->bufptr[1]; | |
| 4479 | 200 continue; |
| 201 } | |
| 4481 | 202 s->bufpos = s->buf + length; |
| 4479 | 203 } |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
204 |
| 4479 | 205 level = CONVERT_LEVEL; |
| 206 bias = CONVERT_BIAS; | |
| 207 | |
| 208 flags |= DTS_ADJUST_LEVEL; | |
| 4481 | 209 if(dts_frame(s->state, s->buf, &flags, &level, bias)) { |
| 4479 | 210 av_log(avctx, AV_LOG_ERROR, "dts_frame() failed\n"); |
| 211 goto end; | |
|
3267
8072ed8993f6
dtsdec.c copies one input packet at a time to a (static) buffer of size
rtognimp
parents:
2979
diff
changeset
|
212 } |
|
8072ed8993f6
dtsdec.c copies one input packet at a time to a (static) buffer of size
rtognimp
parents:
2979
diff
changeset
|
213 |
| 4479 | 214 avctx->sample_rate = sample_rate; |
| 215 avctx->channels = channels_multi(flags); | |
| 216 avctx->bit_rate = bit_rate; | |
| 4478 | 217 |
| 4482 | 218 nblocks = dts_blocks_num(s->state); |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
219 |
| 4482 | 220 for(i = 0; i < nblocks; i++) { |
| 4481 | 221 if(dts_block(s->state)) { |
| 4479 | 222 av_log(avctx, AV_LOG_ERROR, "dts_block() failed\n"); |
| 223 goto end; | |
| 224 } | |
| 4478 | 225 |
| 4482 | 226 convert2s16_multi(dts_samples(s->state), out_samples, flags); |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
227 |
| 4482 | 228 out_samples += 256 * avctx->channels; |
| 229 *data_size += 256 * sizeof(int16_t) * avctx->channels; | |
| 4478 | 230 } |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
231 |
| 4479 | 232 end: |
| 4481 | 233 s->bufptr = s->buf; |
| 234 s->bufpos = s->buf + HEADER_SIZE; | |
| 4478 | 235 return start - buff; |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
236 } |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
237 |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
238 static int |
| 4478 | 239 dts_decode_init(AVCodecContext * avctx) |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
240 { |
| 4481 | 241 DTSContext *s = avctx->priv_data; |
| 242 s->bufptr = s->buf; | |
| 243 s->bufpos = s->buf + HEADER_SIZE; | |
| 244 s->state = dts_init(0); | |
| 245 if(s->state == NULL) | |
| 4478 | 246 return -1; |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
247 |
| 4478 | 248 return 0; |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
249 } |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
250 |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
251 static int |
| 4481 | 252 dts_decode_end(AVCodecContext * avctx) |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
253 { |
| 4481 | 254 DTSContext *s = avctx->priv_data; |
| 255 dts_free(s->state); | |
| 4478 | 256 return 0; |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
257 } |
|
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
258 |
| 4897 | 259 AVCodec libdts_decoder = { |
| 260 "libdts", | |
| 4478 | 261 CODEC_TYPE_AUDIO, |
| 262 CODEC_ID_DTS, | |
| 4481 | 263 sizeof(DTSContext), |
| 4478 | 264 dts_decode_init, |
| 265 NULL, | |
| 266 dts_decode_end, | |
| 267 dts_decode_frame, | |
|
2123
ef54decf5624
libdts support by (Benjamin Zores <ben at geexbox dot org>)
michael
parents:
diff
changeset
|
268 }; |
