* A mdct based codec using a 256 points large transform
* divided into 32 bands with some mix of scale factors.
* Only mono is supported.
- *
*/
#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 "bitstream.h"
+#include "bswapdsp.h"
#include "fft.h"
#include "internal.h"
#include "sinewin.h"
int sumLenArr[BANDS]; ///< bits for all coeffs in band
int skipFlagRaw[BANDS]; ///< skip flags are stored in raw form or not
int skipFlagBits[BANDS]; ///< bits used to code skip flags
- int skipFlagCount[BANDS]; ///< skipped coeffients per band
+ int skipFlagCount[BANDS]; ///< skipped coefficients per band
int skipFlags[COEFFS]; ///< skip coefficient decoding or not
int codewords[COEFFS]; ///< raw codewords read from bitstream
int decoder_reset;
} IMCChannel;
-typedef struct {
+typedef struct IMCContext {
IMCChannel chctx[2];
/** MDCT tables */
//@}
float sqrt_tab[30];
- GetBitContext gb;
+ BitstreamContext bc;
- DSPContext dsp;
+ BswapDSPContext bdsp;
AVFloatDSPContext fdsp;
FFTContext fft;
DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS / 2];
float *out_samples;
+ int coef0_pos;
+
int8_t cyclTab[32], cyclTab2[32];
float weights1[31], weights2[31];
} IMCContext;
av_log(avctx, AV_LOG_INFO, "FFT init failed\n");
return ret;
}
- ff_dsputil_init(&q->dsp, avctx);
- avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ ff_bswapdsp_init(&q->bdsp);
+ avpriv_float_dsp_init(&q->fdsp, avctx->flags & AV_CODEC_FLAG_BITEXACT);
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO
: AV_CH_LAYOUT_STEREO;
if (stream_format_code & 4)
start = 1;
if (start)
- levlCoeffs[0] = get_bits(&q->gb, 7);
+ levlCoeffs[0] = bitstream_read(&q->bc, 7);
for (i = start; i < BANDS; i++) {
- levlCoeffs[i] = get_vlc2(&q->gb, hufftab[cb_sel[i]]->table,
- hufftab[cb_sel[i]]->bits, 2);
+ levlCoeffs[i] = bitstream_read_vlc(&q->bc, hufftab[cb_sel[i]]->table,
+ hufftab[cb_sel[i]]->bits, 2);
if (levlCoeffs[i] == 17)
- levlCoeffs[i] += get_bits(&q->gb, 4);
+ levlCoeffs[i] += bitstream_read(&q->bc, 4);
}
}
+static void imc_read_level_coeffs_raw(IMCContext *q, int stream_format_code,
+ int *levlCoeffs)
+{
+ int i;
+
+ q->coef0_pos = bitstream_read(&q->bc, 5);
+ levlCoeffs[0] = bitstream_read(&q->bc, 7);
+ for (i = 1; i < BANDS; i++)
+ levlCoeffs[i] = bitstream_read(&q->bc, 4);
+}
+
static void imc_decode_level_coefficients(IMCContext *q, int *levlCoeffBuf,
float *flcoeffs1, float *flcoeffs2)
{
}
}
+static void imc_decode_level_coefficients_raw(IMCContext *q, int *levlCoeffBuf,
+ float *flcoeffs1, float *flcoeffs2)
+{
+ int i, level, pos;
+ float tmp, tmp2;
+
+ pos = q->coef0_pos;
+ flcoeffs1[pos] = 20000.0 / pow (2, levlCoeffBuf[0] * 0.18945); // 0.18945 = log2(10) * 0.05703125
+ flcoeffs2[pos] = log2f(flcoeffs1[pos]);
+ tmp = flcoeffs1[pos];
+ tmp2 = flcoeffs2[pos];
+
+ levlCoeffBuf++;
+ for (i = 0; i < BANDS; i++) {
+ if (i == pos)
+ continue;
+ level = *levlCoeffBuf++;
+ flcoeffs1[i] = tmp * powf(10.0, -level * 0.4375); //todo tab
+ flcoeffs2[i] = tmp2 - 1.4533435415 * level; // 1.4533435415 = log2(10) * 0.4375
+ }
+}
+
/**
* Perform bit allocation depending on bits available
*/
chctx->skipFlagBits[i] = band_tab[i + 1] - band_tab[i];
for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
- chctx->skipFlags[j] = get_bits1(&q->gb);
+ chctx->skipFlags[j] = bitstream_read_bit(&q->bc);
if (chctx->skipFlags[j])
chctx->skipFlagCount[i]++;
}
} else {
for (j = band_tab[i]; j < band_tab[i + 1] - 1; j += 2) {
- if (!get_bits1(&q->gb)) { // 0
+ if (!bitstream_read_bit(&q->bc)) { // 0
chctx->skipFlagBits[i]++;
chctx->skipFlags[j] = 1;
chctx->skipFlags[j + 1] = 1;
chctx->skipFlagCount[i] += 2;
} else {
- if (get_bits1(&q->gb)) { // 11
+ if (bitstream_read_bit(&q->bc)) { // 11
chctx->skipFlagBits[i] += 2;
chctx->skipFlags[j] = 0;
chctx->skipFlags[j + 1] = 1;
} else {
chctx->skipFlagBits[i] += 3;
chctx->skipFlags[j + 1] = 0;
- if (!get_bits1(&q->gb)) { // 100
+ if (!bitstream_read_bit(&q->bc)) { // 100
chctx->skipFlags[j] = 1;
chctx->skipFlagCount[i]++;
} else { // 101
if (j < band_tab[i + 1]) {
chctx->skipFlagBits[i]++;
- if ((chctx->skipFlags[j] = get_bits1(&q->gb)))
+ if ((chctx->skipFlags[j] = bitstream_read_bit(&q->bc)))
chctx->skipFlagCount[i]++;
}
}
cw_len = chctx->CWlengthT[j];
cw = 0;
- if (get_bits_count(&q->gb) + cw_len > 512) {
- av_dlog(NULL, "Band %i coeff %i cw_len %i\n", i, j, cw_len);
+ if (bitstream_tell(&q->bc) + cw_len > 512) {
+ ff_dlog(NULL, "Band %i coeff %i cw_len %i\n", i, j, cw_len);
return AVERROR_INVALIDDATA;
}
if (cw_len && (!chctx->bandFlagsBuf[i] || !chctx->skipFlags[j]))
- cw = get_bits(&q->gb, cw_len);
+ cw = bitstream_read(&q->bc, cw_len);
chctx->codewords[j] = cw;
}
return 0;
}
+static void imc_refine_bit_allocation(IMCContext *q, IMCChannel *chctx)
+{
+ int i, j;
+ int bits, summer;
+
+ for (i = 0; i < BANDS; i++) {
+ chctx->sumLenArr[i] = 0;
+ chctx->skipFlagRaw[i] = 0;
+ for (j = band_tab[i]; j < band_tab[i + 1]; j++)
+ chctx->sumLenArr[i] += chctx->CWlengthT[j];
+ if (chctx->bandFlagsBuf[i])
+ if ((((band_tab[i + 1] - band_tab[i]) * 1.5) > chctx->sumLenArr[i]) && (chctx->sumLenArr[i] > 0))
+ chctx->skipFlagRaw[i] = 1;
+ }
+
+ imc_get_skip_coeff(q, chctx);
+
+ for (i = 0; i < BANDS; i++) {
+ chctx->flcoeffs6[i] = chctx->flcoeffs1[i];
+ /* band has flag set and at least one coded coefficient */
+ if (chctx->bandFlagsBuf[i] && (band_tab[i + 1] - band_tab[i]) != chctx->skipFlagCount[i]) {
+ chctx->flcoeffs6[i] *= q->sqrt_tab[ band_tab[i + 1] - band_tab[i]] /
+ q->sqrt_tab[(band_tab[i + 1] - band_tab[i] - chctx->skipFlagCount[i])];
+ }
+ }
+
+ /* calculate bits left, bits needed and adjust bit allocation */
+ bits = summer = 0;
+
+ for (i = 0; i < BANDS; i++) {
+ if (chctx->bandFlagsBuf[i]) {
+ for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
+ if (chctx->skipFlags[j]) {
+ summer += chctx->CWlengthT[j];
+ chctx->CWlengthT[j] = 0;
+ }
+ }
+ bits += chctx->skipFlagBits[i];
+ summer -= chctx->skipFlagBits[i];
+ }
+ }
+ imc_adjust_bit_allocation(q, chctx, summer);
+}
+
static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
{
int stream_format_code;
int imc_hdr, i, j, ret;
int flag;
- int bits, summer;
+ int bits;
int counter, bitscount;
IMCChannel *chctx = q->chctx + ch;
/* Check the frame header */
- imc_hdr = get_bits(&q->gb, 9);
+ imc_hdr = bitstream_read(&q->bc, 9);
if (imc_hdr & 0x18) {
av_log(avctx, AV_LOG_ERROR, "frame header check failed!\n");
av_log(avctx, AV_LOG_ERROR, "got %X.\n", imc_hdr);
return AVERROR_INVALIDDATA;
}
- stream_format_code = get_bits(&q->gb, 3);
-
- if (stream_format_code & 1) {
- avpriv_request_sample(avctx, "Stream format %X", stream_format_code);
- return AVERROR_PATCHWELCOME;
- }
+ stream_format_code = bitstream_read(&q->bc, 3);
if (stream_format_code & 0x04)
chctx->decoder_reset = 1;
chctx->decoder_reset = 0;
}
- flag = get_bits1(&q->gb);
- imc_read_level_coeffs(q, stream_format_code, chctx->levlCoeffBuf);
+ flag = bitstream_read_bit(&q->bc);
+ if (stream_format_code & 0x1)
+ imc_read_level_coeffs_raw(q, stream_format_code, chctx->levlCoeffBuf);
+ else
+ imc_read_level_coeffs(q, stream_format_code, chctx->levlCoeffBuf);
- if (stream_format_code & 0x4)
+ if (stream_format_code & 0x1)
+ imc_decode_level_coefficients_raw(q, chctx->levlCoeffBuf,
+ chctx->flcoeffs1, chctx->flcoeffs2);
+ else if (stream_format_code & 0x4)
imc_decode_level_coefficients(q, chctx->levlCoeffBuf,
chctx->flcoeffs1, chctx->flcoeffs2);
else
memcpy(chctx->old_floor, chctx->flcoeffs1, 32 * sizeof(float));
counter = 0;
- for (i = 0; i < BANDS; i++) {
- if (chctx->levlCoeffBuf[i] == 16) {
- chctx->bandWidthT[i] = 0;
- counter++;
- } else
- chctx->bandWidthT[i] = band_tab[i + 1] - band_tab[i];
- }
- memset(chctx->bandFlagsBuf, 0, BANDS * sizeof(int));
- for (i = 0; i < BANDS - 1; i++) {
- if (chctx->bandWidthT[i])
- chctx->bandFlagsBuf[i] = get_bits1(&q->gb);
- }
+ if (stream_format_code & 0x1) {
+ for (i = 0; i < BANDS; i++) {
+ chctx->bandWidthT[i] = band_tab[i + 1] - band_tab[i];
+ chctx->bandFlagsBuf[i] = 0;
+ chctx->flcoeffs3[i] = chctx->flcoeffs2[i] * 2;
+ chctx->flcoeffs5[i] = 1.0;
+ }
+ } else {
+ for (i = 0; i < BANDS; i++) {
+ if (chctx->levlCoeffBuf[i] == 16) {
+ chctx->bandWidthT[i] = 0;
+ counter++;
+ } else
+ chctx->bandWidthT[i] = band_tab[i + 1] - band_tab[i];
+ }
+
+ memset(chctx->bandFlagsBuf, 0, BANDS * sizeof(int));
+ for (i = 0; i < BANDS - 1; i++)
+ if (chctx->bandWidthT[i])
+ chctx->bandFlagsBuf[i] = bitstream_read_bit(&q->bc);
- imc_calculate_coeffs(q, chctx->flcoeffs1, chctx->flcoeffs2, chctx->bandWidthT, chctx->flcoeffs3, chctx->flcoeffs5);
+ imc_calculate_coeffs(q, chctx->flcoeffs1, chctx->flcoeffs2,
+ chctx->bandWidthT, chctx->flcoeffs3,
+ chctx->flcoeffs5);
+ }
bitscount = 0;
/* first 4 bands will be assigned 5 bits per coefficient */
chctx->CWlengthT[1] = 5;
chctx->CWlengthT[2] = 5;
for (i = 1; i < 4; i++) {
- bits = (chctx->levlCoeffBuf[i] == 16) ? 0 : 5;
+ if (stream_format_code & 0x1)
+ bits = 5;
+ else
+ bits = (chctx->levlCoeffBuf[i] == 16) ? 0 : 5;
chctx->bitsBandT[i] = bits;
for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
chctx->CWlengthT[j] = bits;
}
if ((ret = bit_allocation(q, chctx, stream_format_code,
- 512 - bitscount - get_bits_count(&q->gb),
+ 512 - bitscount - bitstream_tell(&q->bc),
flag)) < 0) {
av_log(avctx, AV_LOG_ERROR, "Bit allocations failed\n");
chctx->decoder_reset = 1;
return ret;
}
- for (i = 0; i < BANDS; i++) {
- chctx->sumLenArr[i] = 0;
- chctx->skipFlagRaw[i] = 0;
- for (j = band_tab[i]; j < band_tab[i + 1]; j++)
- chctx->sumLenArr[i] += chctx->CWlengthT[j];
- if (chctx->bandFlagsBuf[i])
- if ((((band_tab[i + 1] - band_tab[i]) * 1.5) > chctx->sumLenArr[i]) && (chctx->sumLenArr[i] > 0))
- chctx->skipFlagRaw[i] = 1;
- }
-
- imc_get_skip_coeff(q, chctx);
-
- for (i = 0; i < BANDS; i++) {
- chctx->flcoeffs6[i] = chctx->flcoeffs1[i];
- /* band has flag set and at least one coded coefficient */
- if (chctx->bandFlagsBuf[i] && (band_tab[i + 1] - band_tab[i]) != chctx->skipFlagCount[i]) {
- chctx->flcoeffs6[i] *= q->sqrt_tab[ band_tab[i + 1] - band_tab[i]] /
- q->sqrt_tab[(band_tab[i + 1] - band_tab[i] - chctx->skipFlagCount[i])];
- }
- }
-
- /* calculate bits left, bits needed and adjust bit allocation */
- bits = summer = 0;
-
- for (i = 0; i < BANDS; i++) {
- if (chctx->bandFlagsBuf[i]) {
- for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
- if (chctx->skipFlags[j]) {
- summer += chctx->CWlengthT[j];
- chctx->CWlengthT[j] = 0;
- }
- }
- bits += chctx->skipFlagBits[i];
- summer -= chctx->skipFlagBits[i];
- }
+ if (stream_format_code & 0x1) {
+ for (i = 0; i < BANDS; i++)
+ chctx->skipFlags[i] = 0;
+ } else {
+ imc_refine_bit_allocation(q, chctx);
}
- imc_adjust_bit_allocation(q, chctx, summer);
for (i = 0; i < BANDS; i++) {
chctx->sumLenArr[i] = 0;
IMCContext *q = avctx->priv_data;
- LOCAL_ALIGNED_16(uint16_t, buf16, [IMC_BLOCK_SIZE / 2]);
+ LOCAL_ALIGNED_16(uint16_t, buf16, [(IMC_BLOCK_SIZE + AV_INPUT_BUFFER_PADDING_SIZE) / 2]);
if (buf_size < IMC_BLOCK_SIZE * avctx->channels) {
av_log(avctx, AV_LOG_ERROR, "frame too small!\n");
for (i = 0; i < avctx->channels; i++) {
q->out_samples = (float *)frame->extended_data[i];
- q->dsp.bswap16_buf(buf16, (const uint16_t*)buf, IMC_BLOCK_SIZE / 2);
+ q->bdsp.bswap16_buf(buf16, (const uint16_t *) buf, IMC_BLOCK_SIZE / 2);
- init_get_bits(&q->gb, (const uint8_t*)buf16, IMC_BLOCK_SIZE * 8);
+ bitstream_init(&q->bc, (const uint8_t*)buf16, IMC_BLOCK_SIZE * 8);
buf += IMC_BLOCK_SIZE;
AVCodec ff_imc_decoder = {
.name = "imc",
+ .long_name = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"),
.type = AVMEDIA_TYPE_AUDIO,
.id = AV_CODEC_ID_IMC,
.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("IMC (Intel Music Coder)"),
+ .capabilities = AV_CODEC_CAP_DR1,
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
};
AVCodec ff_iac_decoder = {
.name = "iac",
+ .long_name = NULL_IF_CONFIG_SMALL("IAC (Indeo Audio Coder)"),
.type = AVMEDIA_TYPE_AUDIO,
.id = AV_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)"),
+ .capabilities = AV_CODEC_CAP_DR1,
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },
};