Indeo Audio decoder

pull/59/head
Kostya Shishkov 13 years ago
parent 34271cabac
commit c6061443f7
  1. 2
      Changelog
  2. 1
      doc/general.texi
  3. 1
      libavcodec/Makefile
  4. 1
      libavcodec/allcodecs.c
  5. 1
      libavcodec/avcodec.h
  6. 72
      libavcodec/imc.c
  7. 19
      libavcodec/imcdata.h
  8. 4
      libavcodec/version.h
  9. 1
      libavformat/riff.c

@ -23,6 +23,8 @@ version <next>:
- audio mix filter - audio mix filter
- avprobe output is now standard INI or JSON. The old format can still - avprobe output is now standard INI or JSON. The old format can still
be used with -of old. be used with -of old.
- Indeo Audio decoder
version 0.8: version 0.8:

@ -706,6 +706,7 @@ following image formats are supported:
@tab encoding supported through external library libgsm @tab encoding supported through external library libgsm
@item GSM Microsoft variant @tab E @tab X @item GSM Microsoft variant @tab E @tab X
@tab encoding supported through external library libgsm @tab encoding supported through external library libgsm
@item IAC (Indeo Audio Coder) @tab @tab X
@item IMC (Intel Music Coder) @tab @tab X @item IMC (Intel Music Coder) @tab @tab X
@item MACE (Macintosh Audio Compression/Expansion) 3:1 @tab @tab X @item MACE (Macintosh Audio Compression/Expansion) 3:1 @tab @tab X
@item MACE (Macintosh Audio Compression/Expansion) 6:1 @tab @tab X @item MACE (Macintosh Audio Compression/Expansion) 6:1 @tab @tab X

@ -197,6 +197,7 @@ OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o
OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o
OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o
OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o
OBJS-$(CONFIG_IAC_DECODER) += imc.o
OBJS-$(CONFIG_IDCIN_DECODER) += idcinvideo.o OBJS-$(CONFIG_IDCIN_DECODER) += idcinvideo.o
OBJS-$(CONFIG_IFF_BYTERUN1_DECODER) += iff.o OBJS-$(CONFIG_IFF_BYTERUN1_DECODER) += iff.o
OBJS-$(CONFIG_IFF_ILBM_DECODER) += iff.o OBJS-$(CONFIG_IFF_ILBM_DECODER) += iff.o

@ -260,6 +260,7 @@ void avcodec_register_all(void)
REGISTER_ENCDEC (FLAC, flac); REGISTER_ENCDEC (FLAC, flac);
REGISTER_DECODER (GSM, gsm); REGISTER_DECODER (GSM, gsm);
REGISTER_DECODER (GSM_MS, gsm_ms); REGISTER_DECODER (GSM_MS, gsm_ms);
REGISTER_DECODER (IAC, iac);
REGISTER_DECODER (IMC, imc); REGISTER_DECODER (IMC, imc);
REGISTER_DECODER (MACE3, mace3); REGISTER_DECODER (MACE3, mace3);
REGISTER_DECODER (MACE6, mace6); REGISTER_DECODER (MACE6, mace6);

@ -393,6 +393,7 @@ enum CodecID {
CODEC_ID_8SVX_FIB, CODEC_ID_8SVX_FIB,
CODEC_ID_BMV_AUDIO, CODEC_ID_BMV_AUDIO,
CODEC_ID_RALF, CODEC_ID_RALF,
CODEC_ID_IAC,
/* subtitle codecs */ /* subtitle codecs */
CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs. CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs.

@ -79,7 +79,7 @@ typedef struct IMCChannel {
typedef struct { typedef struct {
AVFrame frame; AVFrame frame;
IMCChannel chctx[1]; IMCChannel chctx[2];
/** MDCT tables */ /** MDCT tables */
//@{ //@{
@ -98,6 +98,9 @@ typedef struct {
FFTContext fft; FFTContext fft;
DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS / 2]; DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS / 2];
float *out_samples; float *out_samples;
int8_t cyclTab[32], cyclTab2[32];
float weights1[31], weights2[31];
} IMCContext; } IMCContext;
static VLC huffman_vlc[4][4]; static VLC huffman_vlc[4][4];
@ -117,7 +120,8 @@ static av_cold int imc_decode_init(AVCodecContext *avctx)
IMCContext *q = avctx->priv_data; IMCContext *q = avctx->priv_data;
double r1, r2; double r1, r2;
if (avctx->channels != 1) { if ((avctx->codec_id == CODEC_ID_IMC && avctx->channels != 1)
|| (avctx->codec_id == CODEC_ID_IAC && avctx->channels > 2)) {
av_log_ask_for_sample(avctx, "Number of channels is not supported\n"); av_log_ask_for_sample(avctx, "Number of channels is not supported\n");
return AVERROR_PATCHWELCOME; return AVERROR_PATCHWELCOME;
} }
@ -169,6 +173,18 @@ static av_cold int imc_decode_init(AVCodecContext *avctx)
} }
q->one_div_log2 = 1 / log(2); q->one_div_log2 = 1 / log(2);
memcpy(q->cyclTab, cyclTab, sizeof(cyclTab));
memcpy(q->cyclTab2, cyclTab2, sizeof(cyclTab2));
if (avctx->codec_id == CODEC_ID_IAC) {
q->cyclTab[29] = 31;
q->cyclTab2[31] = 28;
memcpy(q->weights1, iac_weights1, sizeof(iac_weights1));
memcpy(q->weights2, iac_weights2, sizeof(iac_weights2));
} else {
memcpy(q->weights1, imc_weights1, sizeof(imc_weights1));
memcpy(q->weights2, imc_weights2, sizeof(imc_weights2));
}
if ((ret = ff_fft_init(&q->fft, 7, 1))) { if ((ret = ff_fft_init(&q->fft, 7, 1))) {
av_log(avctx, AV_LOG_INFO, "FFT init failed\n"); av_log(avctx, AV_LOG_INFO, "FFT init failed\n");
return ret; return ret;
@ -210,13 +226,13 @@ static void imc_calculate_coeffs(IMCContext *q, float *flcoeffs1,
} }
for (i = 0; i < BANDS; i++) { for (i = 0; i < BANDS; i++) {
for (cnt2 = i; cnt2 < cyclTab[i]; cnt2++) for (cnt2 = i; cnt2 < q->cyclTab[i]; cnt2++)
flcoeffs5[cnt2] = flcoeffs5[cnt2] + workT3[i]; flcoeffs5[cnt2] = flcoeffs5[cnt2] + workT3[i];
workT2[cnt2 - 1] = workT2[cnt2 - 1] + workT3[i]; workT2[cnt2 - 1] = workT2[cnt2 - 1] + workT3[i];
} }
for (i = 1; i < BANDS; i++) { for (i = 1; i < BANDS; i++) {
accum = (workT2[i - 1] + accum) * imc_weights1[i - 1]; accum = (workT2[i - 1] + accum) * q->weights1[i - 1];
flcoeffs5[i] += accum; flcoeffs5[i] += accum;
} }
@ -224,7 +240,7 @@ static void imc_calculate_coeffs(IMCContext *q, float *flcoeffs1,
workT2[i] = 0.0; workT2[i] = 0.0;
for (i = 0; i < BANDS; i++) { for (i = 0; i < BANDS; i++) {
for (cnt2 = i - 1; cnt2 > cyclTab2[i]; cnt2--) for (cnt2 = i - 1; cnt2 > q->cyclTab2[i]; cnt2--)
flcoeffs5[cnt2] += workT3[i]; flcoeffs5[cnt2] += workT3[i];
workT2[cnt2+1] += workT3[i]; workT2[cnt2+1] += workT3[i];
} }
@ -232,7 +248,7 @@ static void imc_calculate_coeffs(IMCContext *q, float *flcoeffs1,
accum = 0.0; accum = 0.0;
for (i = BANDS-2; i >= 0; i--) { for (i = BANDS-2; i >= 0; i--) {
accum = (workT2[i+1] + accum) * imc_weights2[i]; accum = (workT2[i+1] + accum) * q->weights2[i];
flcoeffs5[i] += accum; flcoeffs5[i] += accum;
// there is missing code here, but it seems to never be triggered // there is missing code here, but it seems to never be triggered
} }
@ -701,16 +717,17 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
/* Check the frame header */ /* Check the frame header */
imc_hdr = get_bits(&q->gb, 9); imc_hdr = get_bits(&q->gb, 9);
if (imc_hdr != IMC_FRAME_ID) { if (imc_hdr & 0x18) {
av_log(avctx, AV_LOG_ERROR, "imc frame header check failed!\n"); av_log(avctx, AV_LOG_ERROR, "frame header check failed!\n");
av_log(avctx, AV_LOG_ERROR, "got %x instead of 0x21.\n", imc_hdr); av_log(avctx, AV_LOG_ERROR, "got %X.\n", imc_hdr);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
stream_format_code = get_bits(&q->gb, 3); stream_format_code = get_bits(&q->gb, 3);
if (stream_format_code & 1) { if (stream_format_code & 1) {
av_log(avctx, AV_LOG_ERROR, "Stream code format %X is not supported\n", stream_format_code); av_log_ask_for_sample(avctx, "Stream format %X is not supported\n",
return AVERROR_INVALIDDATA; stream_format_code);
return AVERROR_PATCHWELCOME;
} }
// av_log(avctx, AV_LOG_DEBUG, "stream_format_code = %d\n", stream_format_code); // av_log(avctx, AV_LOG_DEBUG, "stream_format_code = %d\n", stream_format_code);
@ -773,6 +790,11 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
} }
} }
} }
if (avctx->codec_id == CODEC_ID_IAC) {
bitscount += !!chctx->bandWidthT[BANDS - 1];
if (!(stream_format_code & 0x2))
bitscount += 16;
}
if ((ret = bit_allocation(q, chctx, stream_format_code, if ((ret = bit_allocation(q, chctx, stream_format_code,
512 - bitscount - get_bits_count(&q->gb), 512 - bitscount - get_bits_count(&q->gb),
@ -860,8 +882,8 @@ static int imc_decode_frame(AVCodecContext *avctx, void *data,
LOCAL_ALIGNED_16(uint16_t, buf16, [IMC_BLOCK_SIZE / 2]); LOCAL_ALIGNED_16(uint16_t, buf16, [IMC_BLOCK_SIZE / 2]);
if (buf_size < IMC_BLOCK_SIZE) { if (buf_size < IMC_BLOCK_SIZE * avctx->channels) {
av_log(avctx, AV_LOG_ERROR, "imc frame too small!\n"); av_log(avctx, AV_LOG_ERROR, "frame too small!\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
@ -885,6 +907,18 @@ static int imc_decode_frame(AVCodecContext *avctx, void *data,
return ret; return ret;
} }
if (avctx->channels == 2) {
float *src = (float*)q->frame.data[0], t1, t2;
for (i = 0; i < COEFFS; i++) {
t1 = src[0];
t2 = src[1];
src[0] = t1 + t2;
src[1] = t1 - t2;
src += 2;
}
}
*got_frame_ptr = 1; *got_frame_ptr = 1;
*(AVFrame *)data = q->frame; *(AVFrame *)data = q->frame;
@ -913,3 +947,15 @@ AVCodec ff_imc_decoder = {
.capabilities = CODEC_CAP_DR1, .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"), .long_name = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"),
}; };
AVCodec ff_iac_decoder = {
.name = "iac",
.type = AVMEDIA_TYPE_AUDIO,
.id = CODEC_ID_IAC,
.priv_data_size = sizeof(IMCContext),
.init = imc_decode_init,
.close = imc_decode_close,
.decode = imc_decode_frame,
.capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("IAC (Indeo Audio Coder)"),
};

@ -44,6 +44,25 @@ static const int8_t cyclTab2[32] = {
12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29}; 23, 24, 25, 26, 27, 28, 29};
static const float iac_weights1[31] = {
0.0538585, 0.0576251, 0.0645592, 0.0494032, 0.0428915, 0.0592188,
0.0604145, 0.0673549, 0.0797351, 0.0972911, 0.119376, 0.144777,
0.17181, 0.198625, 0.242918, 0.262113, 0.278434, 0.310752,
0.319978, 0.328482, 0.354631, 0.380212, 0.388783, 0.400428,
0.43096, 0.462397, 0.479469, 0.499329, 0.534526, 0.568631,
0.589218
};
static const float iac_weights2[31] = {
0.000375307, 0.000450455, 0.000612191, 0.000297262, 0.000202956,
0.000484887, 0.000511777, 0.000686431, 0.00108256, 0.00185267,
0.00321869, 0.00541861, 0.00860266, 0.012726, 0.0219151,
0.0269104, 0.0316774, 0.0426107, 0.046113, 0.0494974,
0.0608692, 0.0734633, 0.0780208, 0.0844921, 0.103034,
0.124606, 0.137421, 0.153336, 0.184296, 0.217792,
0.239742
};
static const float imc_weights1[31] = { static const float imc_weights1[31] = {
0.119595, 0.123124, 0.129192, 9.97377e-2, 8.1923e-2, 9.61153e-2, 8.77885e-2, 8.61174e-2, 0.119595, 0.123124, 0.129192, 9.97377e-2, 8.1923e-2, 9.61153e-2, 8.77885e-2, 8.61174e-2,
9.00882e-2, 9.91658e-2, 0.112991, 0.131126, 0.152886, 0.177292, 0.221782, 0.244917, 0.267386, 9.00882e-2, 9.91658e-2, 0.112991, 0.131126, 0.152886, 0.177292, 0.221782, 0.244917, 0.267386,

@ -27,8 +27,8 @@
*/ */
#define LIBAVCODEC_VERSION_MAJOR 54 #define LIBAVCODEC_VERSION_MAJOR 54
#define LIBAVCODEC_VERSION_MINOR 13 #define LIBAVCODEC_VERSION_MINOR 14
#define LIBAVCODEC_VERSION_MICRO 1 #define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \ LIBAVCODEC_VERSION_MINOR, \

@ -322,6 +322,7 @@ const AVCodecTag ff_codec_wav_tags[] = {
{ CODEC_ID_ATRAC3, 0x0270 }, { CODEC_ID_ATRAC3, 0x0270 },
{ CODEC_ID_ADPCM_G722, 0x028F }, { CODEC_ID_ADPCM_G722, 0x028F },
{ CODEC_ID_IMC, 0x0401 }, { CODEC_ID_IMC, 0x0401 },
{ CODEC_ID_IAC, 0x0402 },
{ CODEC_ID_GSM_MS, 0x1500 }, { CODEC_ID_GSM_MS, 0x1500 },
{ CODEC_ID_TRUESPEECH, 0x1501 }, { CODEC_ID_TRUESPEECH, 0x1501 },
{ CODEC_ID_AAC, 0x1600 }, /* ADTS AAC */ { CODEC_ID_AAC, 0x1600 }, /* ADTS AAC */

Loading…
Cancel
Save