* Copyright (c) 2007-2008 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com>
* Copyright (c) 2007 Justin Ruggles <justin.ruggles@gmail.com>
*
- * This file is part of FFmpeg.
+ * This file is part of Libav.
*
- * FFmpeg is free software; you can redistribute it and/or
+ * Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * FFmpeg is distributed in the hope that it will be useful,
+ * Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
+ * License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string.h>
#include "libavutil/crc.h"
+#include "libavutil/opt.h"
#include "internal.h"
#include "aac_ac3_parser.h"
#include "ac3_parser.h"
#include "ac3dec.h"
#include "ac3dec_data.h"
-
-/** Large enough for maximum possible frame size when the specification limit is ignored */
-#define AC3_FRAME_BUFFER_SIZE 32768
+#include "kbdwin.h"
/**
* table for ungrouping 3 values in 7 bits.
static float dynamic_range_tab[256];
/** Adjustments in dB gain */
-#define LEVEL_PLUS_3DB 1.4142135623730950
-#define LEVEL_PLUS_1POINT5DB 1.1892071150027209
-#define LEVEL_MINUS_1POINT5DB 0.8408964152537145
-#define LEVEL_MINUS_3DB 0.7071067811865476
-#define LEVEL_MINUS_4POINT5DB 0.5946035575013605
-#define LEVEL_MINUS_6DB 0.5000000000000000
-#define LEVEL_MINUS_9DB 0.3535533905932738
-#define LEVEL_ZERO 0.0000000000000000
-#define LEVEL_ONE 1.0000000000000000
-
static const float gain_levels[9] = {
LEVEL_PLUS_3DB,
LEVEL_PLUS_1POINT5DB,
AC3DecodeContext *s = avctx->priv_data;
s->avctx = avctx;
+#if FF_API_DRC_SCALE
+ if (avctx->drc_scale)
+ s->drc_scale = avctx->drc_scale;
+#endif
+
ff_ac3_common_init();
ac3_tables_init();
ff_mdct_init(&s->imdct_256, 8, 1, 1.0);
ff_mdct_init(&s->imdct_512, 9, 1, 1.0);
ff_kbd_window_init(s->window, 5.0, 256);
dsputil_init(&s->dsp, avctx);
+ ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT);
+ ff_fmt_convert_init(&s->fmt_conv, avctx);
av_lfg_init(&s->dith_state, 0);
- /* set bias values for float to int16 conversion */
+ /* set scale value for float to int16 conversion */
+ if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) {
+ s->mul_bias = 1.0f;
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ } else {
s->mul_bias = 32767.0f;
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ }
/* allow downmixing to stereo or mono */
if (avctx->channels > 0 && avctx->request_channels > 0 &&
}
s->downmixed = 1;
- /* allocate context input buffer */
- if (avctx->error_recognition >= FF_ER_CAREFUL) {
- s->input_buffer = av_mallocz(AC3_FRAME_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
- if (!s->input_buffer)
- return AVERROR(ENOMEM);
- }
-
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
return 0;
}
/* get decoding parameters from header info */
s->bit_alloc_params.sr_code = hdr.sr_code;
+ s->bitstream_mode = hdr.bitstream_mode;
s->channel_mode = hdr.channel_mode;
s->channel_layout = hdr.channel_layout;
s->lfe_on = hdr.lfe_on;
mantissa = b5_mantissas[get_bits(gbc, 4)];
break;
default: /* 6 to 15 */
- mantissa = get_bits(gbc, quantization_tab[bap]);
/* Shift mantissa and sign-extend it. */
- mantissa = (mantissa << (32-quantization_tab[bap]))>>8;
+ mantissa = get_sbits(gbc, quantization_tab[bap]);
+ mantissa <<= 24 - quantization_tab[bap];
break;
}
coeffs[freq] = mantissa >> exps[freq];
float *x = s->tmp_output+128;
for(i=0; i<128; i++)
x[i] = s->transform_coeffs[ch][2*i];
- ff_imdct_half(&s->imdct_256, s->tmp_output, x);
- s->dsp.vector_fmul_window(s->output[ch-1], s->delay[ch-1], s->tmp_output, s->window, 0, 128);
+ s->imdct_256.imdct_half(&s->imdct_256, s->tmp_output, x);
+ s->dsp.vector_fmul_window(s->output[ch-1], s->delay[ch-1], s->tmp_output, s->window, 128);
for(i=0; i<128; i++)
x[i] = s->transform_coeffs[ch][2*i+1];
- ff_imdct_half(&s->imdct_256, s->delay[ch-1], x);
+ s->imdct_256.imdct_half(&s->imdct_256, s->delay[ch-1], x);
} else {
- ff_imdct_half(&s->imdct_512, s->tmp_output, s->transform_coeffs[ch]);
- s->dsp.vector_fmul_window(s->output[ch-1], s->delay[ch-1], s->tmp_output, s->window, 0, 128);
+ s->imdct_512.imdct_half(&s->imdct_512, s->tmp_output, s->transform_coeffs[ch]);
+ s->dsp.vector_fmul_window(s->output[ch-1], s->delay[ch-1], s->tmp_output, s->window, 128);
memcpy(s->delay[ch-1], s->tmp_output+128, 128*sizeof(float));
}
}
do {
if(get_bits1(gbc)) {
s->dynamic_range[i] = ((dynamic_range_tab[get_bits(gbc, 8)]-1.0) *
- s->avctx->drc_scale)+1.0;
+ s->drc_scale)+1.0;
} else if(blk == 0) {
s->dynamic_range[i] = 1.0f;
}
/* channel delta offset, len and bit allocation */
for (ch = !cpl_in_use; ch <= fbw_channels; ch++) {
if (s->dba_mode[ch] == DBA_NEW) {
- s->dba_nsegs[ch] = get_bits(gbc, 3);
- for (seg = 0; seg <= s->dba_nsegs[ch]; seg++) {
+ s->dba_nsegs[ch] = get_bits(gbc, 3) + 1;
+ for (seg = 0; seg < s->dba_nsegs[ch]; seg++) {
s->dba_offsets[ch][seg] = get_bits(gbc, 5);
s->dba_lengths[ch][seg] = get_bits(gbc, 4);
s->dba_values[ch][seg] = get_bits(gbc, 3);
/* Compute bit allocation */
const uint8_t *bap_tab = s->channel_uses_aht[ch] ?
ff_eac3_hebap_tab : ff_ac3_bap_tab;
- ff_ac3_bit_alloc_calc_bap(s->mask[ch], s->psd[ch],
+ s->ac3dsp.bit_alloc_calc_bap(s->mask[ch], s->psd[ch],
s->start_freq[ch], s->end_freq[ch],
s->snr_offset[ch],
s->bit_alloc_params.floor,
} else {
gain *= s->dynamic_range[0];
}
- s->dsp.int32_to_float_fmul_scalar(s->transform_coeffs[ch], s->fixed_coeffs[ch], gain, 256);
+ s->fmt_conv.int32_to_float_fmul_scalar(s->transform_coeffs[ch], s->fixed_coeffs[ch], gain, 256);
}
/* apply spectral extension to high frequency bins */
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
AC3DecodeContext *s = avctx->priv_data;
- int16_t *out_samples = (int16_t *)data;
+ float *out_samples_flt = data;
+ int16_t *out_samples_s16 = data;
int blk, ch, err;
const uint8_t *channel_map;
const float *output[AC3_MAX_CHANNELS];
- /* initialize the GetBitContext with the start of valid AC-3 Frame */
- if (s->input_buffer) {
- /* copy input buffer to decoder context to avoid reading past the end
- of the buffer, which can be caused by a damaged input stream. */
+ /* copy input buffer to decoder context to avoid reading past the end
+ of the buffer, which can be caused by a damaged input stream. */
+ if (buf_size >= 2 && AV_RB16(buf) == 0x770B) {
+ // seems to be byte-swapped AC-3
+ int cnt = FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE) >> 1;
+ s->dsp.bswap16_buf((uint16_t *)s->input_buffer, (const uint16_t *)buf, cnt);
+ } else
memcpy(s->input_buffer, buf, FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE));
- init_get_bits(&s->gbc, s->input_buffer, buf_size * 8);
- } else {
- init_get_bits(&s->gbc, buf, buf_size * 8);
- }
+ buf = s->input_buffer;
+ /* initialize the GetBitContext with the start of valid AC-3 Frame */
+ init_get_bits(&s->gbc, buf, buf_size * 8);
/* parse the syncinfo */
*data_size = 0;
if(s->out_channels < s->channels)
s->output_mode = s->out_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO;
}
+ /* set audio service type based on bitstream mode for AC-3 */
+ avctx->audio_service_type = s->bitstream_mode;
+ if (s->bitstream_mode == 0x7 && s->channels > 1)
+ avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
/* decode the audio blocks */
channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on];
av_log(avctx, AV_LOG_ERROR, "error decoding the audio block\n");
err = 1;
}
- s->dsp.float_to_int16_interleave(out_samples, output, 256, s->out_channels);
- out_samples += 256 * s->out_channels;
+ if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
+ s->fmt_conv.float_interleave(out_samples_flt, output, 256,
+ s->out_channels);
+ out_samples_flt += 256 * s->out_channels;
+ } else {
+ s->fmt_conv.float_to_int16_interleave(out_samples_s16, output, 256,
+ s->out_channels);
+ out_samples_s16 += 256 * s->out_channels;
+ }
}
- *data_size = s->num_blocks * 256 * avctx->channels * sizeof (int16_t);
+ *data_size = s->num_blocks * 256 * avctx->channels *
+ av_get_bytes_per_sample(avctx->sample_fmt);
return FFMIN(buf_size, s->frame_size);
}
ff_mdct_end(&s->imdct_512);
ff_mdct_end(&s->imdct_256);
- av_freep(&s->input_buffer);
-
return 0;
}
+#define OFFSET(x) offsetof(AC3DecodeContext, x)
+#define PAR (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM)
+static const AVOption options[] = {
+ { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {1.0}, 0.0, 1.0, PAR },
+ { NULL},
+};
+
+static const AVClass ac3_decoder_class = {
+ .class_name = "AC3 decoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVCodec ff_ac3_decoder = {
.name = "ac3",
.type = AVMEDIA_TYPE_AUDIO,
.close = ac3_decode_end,
.decode = ac3_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
+ .sample_fmts = (const enum AVSampleFormat[]) {
+ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
+ },
+ .priv_class = &ac3_decoder_class,
};
#if CONFIG_EAC3_DECODER
+static const AVClass eac3_decoder_class = {
+ .class_name = "E-AC3 decoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
AVCodec ff_eac3_decoder = {
.name = "eac3",
.type = AVMEDIA_TYPE_AUDIO,
.close = ac3_decode_end,
.decode = ac3_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"),
+ .sample_fmts = (const enum AVSampleFormat[]) {
+ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
+ },
+ .priv_class = &eac3_decoder_class,
};
#endif