#include <stddef.h>
#include <stdio.h>
+#include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
+#include "libavutil/internal.h"
#include "avcodec.h"
#include "get_bits.h"
#include "dsputil.h"
#include "fft.h"
-#include "libavutil/audioconvert.h"
+#include "internal.h"
#include "sinewin.h"
#include "imcdata.h"
} IMCChannel;
typedef struct {
- AVFrame frame;
-
IMCChannel chctx[2];
/** MDCT tables */
GetBitContext gb;
DSPContext dsp;
+ AVFloatDSPContext fdsp;
FFTContext fft;
DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS / 2];
float *out_samples;
IMCContext *q = avctx->priv_data;
double r1, r2;
- if ((avctx->codec_id == AV_CODEC_ID_IMC && avctx->channels != 1)
- || (avctx->codec_id == AV_CODEC_ID_IAC && avctx->channels > 2)) {
- av_log_ask_for_sample(avctx, "Number of channels is not supported\n");
+ if (avctx->codec_id == AV_CODEC_ID_IMC)
+ avctx->channels = 1;
+
+ if (avctx->channels > 2) {
+ avpriv_request_sample(avctx, "Number of channels > 2");
return AVERROR_PATCHWELCOME;
}
return ret;
}
ff_dsputil_init(&q->dsp, avctx);
- avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO
: AV_CH_LAYOUT_STEREO;
- avcodec_get_frame_defaults(&q->frame);
- avctx->coded_frame = &q->frame;
-
return 0;
}
int i;
float re, im;
float *dst1 = q->out_samples;
- float *dst2 = q->out_samples + (COEFFS - 1) * channels;
+ float *dst2 = q->out_samples + (COEFFS - 1);
/* prerotation */
for (i = 0; i < COEFFS / 2; i++) {
+ (q->mdct_sine_window[i * 2] * re);
*dst2 = (q->mdct_sine_window[i * 2] * chctx->last_fft_im[i])
- (q->mdct_sine_window[COEFFS - 1 - i * 2] * re);
- dst1 += channels * 2;
- dst2 -= channels * 2;
+ dst1 += 2;
+ dst2 -= 2;
chctx->last_fft_im[i] = im;
}
}
cw = 0;
if (get_bits_count(&q->gb) + cw_len > 512) {
- // av_log(NULL, 0, "Band %i coeff %i cw_len %i\n", i, j, cw_len);
+ av_dlog(NULL, "Band %i coeff %i cw_len %i\n", i, j, cw_len);
return AVERROR_INVALIDDATA;
}
stream_format_code = get_bits(&q->gb, 3);
if (stream_format_code & 1) {
- av_log_ask_for_sample(avctx, "Stream format %X is not supported\n",
- stream_format_code);
+ avpriv_request_sample(avctx, "Stream format %X", stream_format_code);
return AVERROR_PATCHWELCOME;
}
chctx->decoder_reset = 1;
if (chctx->decoder_reset) {
- memset(q->out_samples, 0, COEFFS * sizeof(*q->out_samples));
for (i = 0; i < BANDS; i++)
chctx->old_floor[i] = 1.0;
for (i = 0; i < COEFFS; i++)
static int imc_decode_frame(AVCodecContext *avctx, void *data,
int *got_frame_ptr, AVPacket *avpkt)
{
+ AVFrame *frame = data;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
int ret, i;
}
/* get output buffer */
- q->frame.nb_samples = COEFFS;
- if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) {
+ frame->nb_samples = COEFFS;
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return ret;
}
for (i = 0; i < avctx->channels; i++) {
- q->out_samples = (float*)q->frame.data[0] + i;
+ q->out_samples = (float *)frame->extended_data[i];
q->dsp.bswap16_buf(buf16, (const uint16_t*)buf, IMC_BLOCK_SIZE / 2);
}
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;
- }
+ q->fdsp.butterflies_float((float *)frame->extended_data[0],
+ (float *)frame->extended_data[1], COEFFS);
}
- *got_frame_ptr = 1;
- *(AVFrame *)data = q->frame;
+ *got_frame_ptr = 1;
return IMC_BLOCK_SIZE * avctx->channels;
}
.decode = imc_decode_frame,
.capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"),
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
+ AV_SAMPLE_FMT_NONE },
};
AVCodec ff_iac_decoder = {
.decode = imc_decode_frame,
.capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("IAC (Indeo Audio Coder)"),
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
+ AV_SAMPLE_FMT_NONE },
};