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