summaryrefslogtreecommitdiff
path: root/contrib/ffmpeg/libavcodec/dtsdec.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ffmpeg/libavcodec/dtsdec.c')
-rw-r--r--contrib/ffmpeg/libavcodec/dtsdec.c404
1 files changed, 176 insertions, 228 deletions
diff --git a/contrib/ffmpeg/libavcodec/dtsdec.c b/contrib/ffmpeg/libavcodec/dtsdec.c
index 456f3fdef..6763572dd 100644
--- a/contrib/ffmpeg/libavcodec/dtsdec.c
+++ b/contrib/ffmpeg/libavcodec/dtsdec.c
@@ -16,305 +16,253 @@
*
* You should have received a copy of the GNU General Public License
* along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifdef HAVE_AV_CONFIG_H
-#undef HAVE_AV_CONFIG_H
-#endif
-
#include "avcodec.h"
#include <dts.h>
#include <stdlib.h>
#include <string.h>
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-
#define BUFFER_SIZE 18726
#define HEADER_SIZE 14
-#ifdef LIBDTS_FIXED
-#define CONVERT_LEVEL (1 << 26)
-#define CONVERT_BIAS 0
-#else
#define CONVERT_LEVEL 1
-#define CONVERT_BIAS 384
-#endif
-
-static inline
-int16_t convert (int32_t i)
-{
-#ifdef LIBDTS_FIXED
- i >>= 15;
-#else
- i -= 0x43c00000;
-#endif
- return (i > 32767) ? 32767 : ((i < -32768) ? -32768 : i);
-}
-
-static void
-convert2s16_2 (sample_t * _f, int16_t * s16)
-{
- int i;
- int32_t * f = (int32_t *) _f;
-
- for (i = 0; i < 256; i++)
- {
- s16[2*i] = convert (f[i]);
- s16[2*i+1] = convert (f[i+256]);
- }
-}
-
-static void
-convert2s16_4 (sample_t * _f, int16_t * s16)
-{
- int i;
- int32_t * f = (int32_t *) _f;
+#define CONVERT_BIAS 0
- for (i = 0; i < 256; i++)
- {
- s16[4*i] = convert (f[i]);
- s16[4*i+1] = convert (f[i+256]);
- s16[4*i+2] = convert (f[i+512]);
- s16[4*i+3] = convert (f[i+768]);
- }
-}
+typedef struct DTSContext {
+ dts_state_t *state;
+ uint8_t buf[BUFFER_SIZE];
+ uint8_t *bufptr;
+ uint8_t *bufpos;
+} DTSContext;
-static void
-convert2s16_5 (sample_t * _f, int16_t * s16)
+static inline int16_t
+convert(sample_t s)
{
- int i;
- int32_t * f = (int32_t *) _f;
-
- for (i = 0; i < 256; i++)
- {
- s16[5*i] = convert (f[i]);
- s16[5*i+1] = convert (f[i+256]);
- s16[5*i+2] = convert (f[i+512]);
- s16[5*i+3] = convert (f[i+768]);
- s16[5*i+4] = convert (f[i+1024]);
- }
+ return s * 0x7fff;
}
static void
-convert2s16_multi (sample_t * _f, int16_t * s16, int flags)
+convert2s16_multi(sample_t *f, int16_t *s16, int flags)
{
- int i;
- int32_t * f = (int32_t *) _f;
+ int i;
- switch (flags)
- {
+ switch(flags & (DTS_CHANNEL_MASK | DTS_LFE)){
case DTS_MONO:
- for (i = 0; i < 256; i++)
- {
- s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0;
- s16[5*i+4] = convert (f[i]);
+ for(i = 0; i < 256; i++){
+ s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0;
+ s16[5*i+4] = convert(f[i]);
}
- break;
case DTS_CHANNEL:
case DTS_STEREO:
case DTS_DOLBY:
- convert2s16_2 (_f, s16);
- break;
+ for(i = 0; i < 256; i++){
+ s16[2*i] = convert(f[i]);
+ s16[2*i+1] = convert(f[i+256]);
+ }
case DTS_3F:
- for (i = 0; i < 256; i++)
- {
- s16[5*i] = convert (f[i]);
- s16[5*i+1] = convert (f[i+512]);
- s16[5*i+2] = s16[5*i+3] = 0;
- s16[5*i+4] = convert (f[i+256]);
+ for(i = 0; i < 256; i++){
+ s16[5*i] = convert(f[i+256]);
+ s16[5*i+1] = convert(f[i+512]);
+ s16[5*i+2] = s16[5*i+3] = 0;
+ s16[5*i+4] = convert(f[i]);
}
- break;
case DTS_2F2R:
- convert2s16_4 (_f, s16);
- break;
+ for(i = 0; i < 256; i++){
+ s16[4*i] = convert(f[i]);
+ s16[4*i+1] = convert(f[i+256]);
+ s16[4*i+2] = convert(f[i+512]);
+ s16[4*i+3] = convert(f[i+768]);
+ }
case DTS_3F2R:
- convert2s16_5 (_f, s16);
- break;
+ for(i = 0; i < 256; i++){
+ s16[5*i] = convert(f[i+256]);
+ s16[5*i+1] = convert(f[i+512]);
+ s16[5*i+2] = convert(f[i+768]);
+ s16[5*i+3] = convert(f[i+1024]);
+ s16[5*i+4] = convert(f[i]);
+ }
case DTS_MONO | DTS_LFE:
- for (i = 0; i < 256; i++)
- {
- s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0;
- s16[6*i+4] = convert (f[i+256]);
- s16[6*i+5] = convert (f[i]);
+ for(i = 0; i < 256; i++){
+ s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0;
+ s16[6*i+4] = convert(f[i]);
+ s16[6*i+5] = convert(f[i+256]);
}
- break;
case DTS_CHANNEL | DTS_LFE:
case DTS_STEREO | DTS_LFE:
case DTS_DOLBY | DTS_LFE:
- for (i = 0; i < 256; i++)
- {
- s16[6*i] = convert (f[i+256]);
- s16[6*i+1] = convert (f[i+512]);
- s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0;
- s16[6*i+5] = convert (f[i]);
+ for(i = 0; i < 256; i++){
+ s16[6*i] = convert(f[i]);
+ s16[6*i+1] = convert(f[i+256]);
+ s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0;
+ s16[6*i+5] = convert(f[i+512]);
}
- break;
case DTS_3F | DTS_LFE:
- for (i = 0; i < 256; i++)
- {
- s16[6*i] = convert (f[i+256]);
- s16[6*i+1] = convert (f[i+768]);
- s16[6*i+2] = s16[6*i+3] = 0;
- s16[6*i+4] = convert (f[i+512]);
- s16[6*i+5] = convert (f[i]);
+ for(i = 0; i < 256; i++){
+ s16[6*i] = convert(f[i+256]);
+ s16[6*i+1] = convert(f[i+512]);
+ s16[6*i+2] = s16[6*i+3] = 0;
+ s16[6*i+4] = convert(f[i]);
+ s16[6*i+5] = convert(f[i+768]);
}
- break;
case DTS_2F2R | DTS_LFE:
- for (i = 0; i < 256; i++)
- {
- s16[6*i] = convert (f[i+256]);
- s16[6*i+1] = convert (f[i+512]);
- s16[6*i+2] = convert (f[i+768]);
- s16[6*i+3] = convert (f[i+1024]);
- s16[6*i+4] = 0;
- s16[6*i+5] = convert (f[i]);
+ for(i = 0; i < 256; i++){
+ s16[6*i] = convert(f[i]);
+ s16[6*i+1] = convert(f[i+256]);
+ s16[6*i+2] = convert(f[i+512]);
+ s16[6*i+3] = convert(f[i+768]);
+ s16[6*i+4] = 0;
+ s16[6*i+5] = convert(f[i+1024]);
}
- break;
case DTS_3F2R | DTS_LFE:
- for (i = 0; i < 256; i++)
- {
- s16[6*i] = convert (f[i+256]);
- s16[6*i+1] = convert (f[i+768]);
- s16[6*i+2] = convert (f[i+1024]);
- s16[6*i+3] = convert (f[i+1280]);
- s16[6*i+4] = convert (f[i+512]);
- s16[6*i+5] = convert (f[i]);
+ for(i = 0; i < 256; i++){
+ s16[6*i] = convert(f[i+256]);
+ s16[6*i+1] = convert(f[i+512]);
+ s16[6*i+2] = convert(f[i+768]);
+ s16[6*i+3] = convert(f[i+1024]);
+ s16[6*i+4] = convert(f[i]);
+ s16[6*i+5] = convert(f[i+1280]);
}
- break;
}
}
static int
-channels_multi (int flags)
+channels_multi(int flags)
{
- if (flags & DTS_LFE)
- return 6;
- else if (flags & 1) /* center channel */
- return 5;
- else if ((flags & DTS_CHANNEL_MASK) == DTS_2F2R)
- return 4;
- else
- return 2;
+ switch(flags & (DTS_CHANNEL_MASK | DTS_LFE)){
+ case DTS_CHANNEL:
+ case DTS_STEREO:
+ case DTS_DOLBY:
+ return 2;
+ case DTS_2F2R:
+ return 4;
+ case DTS_MONO:
+ case DTS_3F:
+ case DTS_3F2R:
+ return 5;
+ case DTS_MONO | DTS_LFE:
+ case DTS_CHANNEL | DTS_LFE:
+ case DTS_STEREO | DTS_LFE:
+ case DTS_DOLBY | DTS_LFE:
+ case DTS_3F | DTS_LFE:
+ case DTS_2F2R | DTS_LFE:
+ case DTS_3F2R | DTS_LFE:
+ return 6;
+ }
+
+ return -1;
}
static int
-dts_decode_frame (AVCodecContext *avctx, void *data, int *data_size,
- uint8_t *buff, int buff_size)
+dts_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
+ uint8_t * buff, int buff_size)
{
- uint8_t * start = buff;
- uint8_t * end = buff + buff_size;
- static uint8_t buf[BUFFER_SIZE];
- static uint8_t * bufptr = buf;
- static uint8_t * bufpos = buf + HEADER_SIZE;
+ DTSContext *s = avctx->priv_data;
+ uint8_t *start = buff;
+ uint8_t *end = buff + buff_size;
+ int16_t *out_samples = data;
+ int sample_rate;
+ int frame_length;
+ int flags;
+ int bit_rate;
+ int len;
+ level_t level;
+ sample_t bias;
+ int nblocks;
+ int i;
+
+ *data_size = 0;
- static int sample_rate;
- static int frame_length;
- static int flags;
- int bit_rate;
- int len;
- dts_state_t *state = avctx->priv_data;
+ while(1) {
+ int length;
- *data_size = 0;
+ len = end - start;
+ if(!len)
+ break;
+ if(len > s->bufpos - s->bufptr)
+ len = s->bufpos - s->bufptr;
+ memcpy(s->bufptr, start, len);
+ s->bufptr += len;
+ start += len;
+ if(s->bufptr != s->bufpos)
+ return start - buff;
+ if(s->bufpos != s->buf + HEADER_SIZE)
+ break;
- while (1)
- {
- len = end - start;
- if (!len)
- break;
- if (len > bufpos - bufptr)
- len = bufpos - bufptr;
- memcpy (bufptr, start, len);
- bufptr += len;
- start += len;
- if (bufptr != bufpos)
- return start - buff;
- if (bufpos != buf + HEADER_SIZE)
- break;
+ length = dts_syncinfo(s->state, s->buf, &flags, &sample_rate,
+ &bit_rate, &frame_length);
+ if(!length) {
+ av_log(NULL, AV_LOG_INFO, "skip\n");
+ for(s->bufptr = s->buf; s->bufptr < s->buf + HEADER_SIZE - 1; s->bufptr++)
+ s->bufptr[0] = s->bufptr[1];
+ continue;
+ }
+ s->bufpos = s->buf + length;
+ }
- {
- int length;
+ level = CONVERT_LEVEL;
+ bias = CONVERT_BIAS;
- length = dts_syncinfo (state, buf, &flags, &sample_rate,
- &bit_rate, &frame_length);
- if (!length)
- {
- av_log (NULL, AV_LOG_INFO, "skip\n");
- for (bufptr = buf; bufptr < buf + HEADER_SIZE-1; bufptr++)
- bufptr[0] = bufptr[1];
- continue;
- }
- bufpos = buf + length;
- }
+ flags |= DTS_ADJUST_LEVEL;
+ if(dts_frame(s->state, s->buf, &flags, &level, bias)) {
+ av_log(avctx, AV_LOG_ERROR, "dts_frame() failed\n");
+ goto end;
}
- {
- level_t level;
- sample_t bias;
- int i;
+ avctx->sample_rate = sample_rate;
+ avctx->channels = channels_multi(flags);
+ avctx->bit_rate = bit_rate;
+
+ nblocks = dts_blocks_num(s->state);
- flags = 2; /* ???????????? */
- level = CONVERT_LEVEL;
- bias = CONVERT_BIAS;
+ for(i = 0; i < nblocks; i++) {
+ if(dts_block(s->state)) {
+ av_log(avctx, AV_LOG_ERROR, "dts_block() failed\n");
+ goto end;
+ }
- flags |= DTS_ADJUST_LEVEL;
- if (dts_frame (state, buf, &flags, &level, bias))
- goto error;
- avctx->sample_rate = sample_rate;
- avctx->channels = channels_multi (flags);
- avctx->bit_rate = bit_rate;
- for (i = 0; i < dts_blocks_num (state); i++)
- {
- if (dts_block (state))
- goto error;
- {
- int chans;
- chans = channels_multi (flags);
- convert2s16_multi (dts_samples (state), data,
- flags & (DTS_CHANNEL_MASK | DTS_LFE));
+ convert2s16_multi(dts_samples(s->state), out_samples, flags);
- data += 256 * sizeof (int16_t) * chans;
- *data_size += 256 * sizeof (int16_t) * chans;
- }
- }
- bufptr = buf;
- bufpos = buf + HEADER_SIZE;
- return start-buff;
- error:
- av_log (NULL, AV_LOG_ERROR, "error\n");
- bufptr = buf;
- bufpos = buf + HEADER_SIZE;
- }
+ out_samples += 256 * avctx->channels;
+ *data_size += 256 * sizeof(int16_t) * avctx->channels;
+ }
- return start-buff;
+end:
+ s->bufptr = s->buf;
+ s->bufpos = s->buf + HEADER_SIZE;
+ return start - buff;
}
static int
-dts_decode_init (AVCodecContext *avctx)
+dts_decode_init(AVCodecContext * avctx)
{
- avctx->priv_data = dts_init (0);
- if (avctx->priv_data == NULL)
- return -1;
+ DTSContext *s = avctx->priv_data;
+ s->bufptr = s->buf;
+ s->bufpos = s->buf + HEADER_SIZE;
+ s->state = dts_init(0);
+ if(s->state == NULL)
+ return -1;
- return 0;
+ return 0;
}
static int
-dts_decode_end (AVCodecContext *s)
+dts_decode_end(AVCodecContext * avctx)
{
- return 0;
+ DTSContext *s = avctx->priv_data;
+ dts_free(s->state);
+ return 0;
}
AVCodec dts_decoder = {
- "dts",
- CODEC_TYPE_AUDIO,
- CODEC_ID_DTS,
- sizeof (dts_state_t *),
- dts_decode_init,
- NULL,
- dts_decode_end,
- dts_decode_frame,
+ "dts",
+ CODEC_TYPE_AUDIO,
+ CODEC_ID_DTS,
+ sizeof(DTSContext),
+ dts_decode_init,
+ NULL,
+ dts_decode_end,
+ dts_decode_frame,
};