#include "libavutil/crc.h"
#include "libavutil/downmix_info.h"
#include "libavutil/opt.h"
+#include "libavutil/thread.h"
#include "bswapdsp.h"
#include "internal.h"
#include "aac_ac3_parser.h"
{ { 2, 7 }, { 5, 5 }, { 7, 2 }, { 6, 7 }, { 7, 6 }, },
};
-static const uint64_t custom_channel_map_locations[16][2] = {
- { 1, AV_CH_FRONT_LEFT },
- { 1, AV_CH_FRONT_CENTER },
- { 1, AV_CH_FRONT_RIGHT },
- { 1, AV_CH_SIDE_LEFT },
- { 1, AV_CH_SIDE_RIGHT },
- { 0, AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER },
- { 0, AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT },
- { 0, AV_CH_BACK_CENTER },
- { 0, AV_CH_TOP_CENTER },
- { 0, AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT },
- { 0, AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT },
- { 0, AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT},
- { 0, AV_CH_TOP_FRONT_CENTER },
- { 0, AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT },
- { 0, AV_CH_LOW_FREQUENCY_2 },
- { 1, AV_CH_LOW_FREQUENCY },
-};
-
/**
* Symmetrical Dequantization
* reference: Section 7.3.3 Expansion of Mantissas for Symmetrical Quantization
*/
static av_cold int ac3_decode_init(AVCodecContext *avctx)
{
+ static AVOnce init_static_once = AV_ONCE_INIT;
AC3DecodeContext *s = avctx->priv_data;
- int i;
+ int i, ret;
s->avctx = avctx;
- ac3_tables_init();
- ff_mdct_init(&s->imdct_256, 8, 1, 1.0);
- ff_mdct_init(&s->imdct_512, 9, 1, 1.0);
+ if ((ret = ff_mdct_init(&s->imdct_256, 8, 1, 1.0)) < 0 ||
+ (ret = ff_mdct_init(&s->imdct_512, 9, 1, 1.0)) < 0)
+ return ret;
AC3_RENAME(ff_kbd_window_init)(s->window, 5.0, 256);
ff_bswapdsp_init(&s->bdsp);
#if (USE_FIXED)
s->fdsp = avpriv_alloc_fixed_dsp(avctx->flags & AV_CODEC_FLAG_BITEXACT);
#else
- s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
ff_fmt_convert_init(&s->fmt_conv, avctx);
+ s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
#endif
+ if (!s->fdsp)
+ return AVERROR(ENOMEM);
ff_ac3dsp_init(&s->ac3dsp, avctx->flags & AV_CODEC_FLAG_BITEXACT);
av_lfg_init(&s->dith_state, 0);
s->dlyptr[i] = s->delay[i];
}
+ ff_thread_once(&init_static_once, ac3_tables_init);
+
return 0;
}
prevexp += dexp[i] - 2;
if (prevexp > 24U) {
av_log(s->avctx, AV_LOG_ERROR, "exponent %d is out-of-range\n", prevexp);
- return -1;
+ return AVERROR_INVALIDDATA;
}
switch (group_size) {
case 4: dexps[j++] = prevexp;
int buf_size, full_buf_size = avpkt->size;
AC3DecodeContext *s = avctx->priv_data;
int blk, ch, err, offset, ret;
- int got_independent_frame = 0;
+ int i;
+ int skip = 0, got_independent_frame = 0;
const uint8_t *channel_map;
uint8_t extended_channel_map[EAC3_MAX_CHANNELS];
const SHORTFLOAT *output[AC3_MAX_CHANNELS];
s->superframe_size = 0;
buf_size = full_buf_size;
+ for (i = 1; i < buf_size; i += 2) {
+ if (buf[i] == 0x77 || buf[i] == 0x0B) {
+ if ((buf[i] ^ buf[i-1]) == (0x77 ^ 0x0B)) {
+ i--;
+ break;
+ } else if ((buf[i] ^ buf[i+1]) == (0x77 ^ 0x0B)) {
+ break;
+ }
+ }
+ }
+ if (i >= buf_size)
+ return AVERROR_INVALIDDATA;
+ if (i > 10)
+ return i;
+ buf += i;
+ buf_size -= i;
+
/* 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) {
AC3HeaderInfo hdr;
int err;
+ if (buf_size - s->frame_size <= 16) {
+ skip = buf_size - s->frame_size;
+ goto skip;
+ }
+
if ((ret = init_get_bits8(&s->gbc, buf + s->frame_size, buf_size - s->frame_size)) < 0)
return ret;
}
}
}
+skip:
frame->decode_error_flags = err ? FF_DECODE_ERROR_INVALID_BITSTREAM : 0;
channel_layout = ich_layout;
for (ch = 0; ch < 16; ch++) {
if (s->channel_map & (1 << (EAC3_MAX_CHANNELS - ch - 1))) {
- channel_layout |= custom_channel_map_locations[ch][1];
+ channel_layout |= ff_eac3_custom_channel_map_locations[ch][1];
}
}
if (av_get_channel_layout_nb_channels(channel_layout) > EAC3_MAX_CHANNELS) {
for (ch = 0; ch < EAC3_MAX_CHANNELS; ch++) {
if (s->channel_map & (1 << (EAC3_MAX_CHANNELS - ch - 1))) {
- if (custom_channel_map_locations[ch][0]) {
+ if (ff_eac3_custom_channel_map_locations[ch][0]) {
int index = av_get_channel_layout_channel_index(channel_layout,
- custom_channel_map_locations[ch][1]);
+ ff_eac3_custom_channel_map_locations[ch][1]);
if (index < 0)
return AVERROR_INVALIDDATA;
if (extend >= channel_map_size)
int i;
for (i = 0; i < 64; i++) {
- if ((1LL << i) & custom_channel_map_locations[ch][1]) {
+ if ((1ULL << i) & ff_eac3_custom_channel_map_locations[ch][1]) {
int index = av_get_channel_layout_channel_index(channel_layout,
- 1LL << i);
+ 1ULL << i);
if (index < 0)
return AVERROR_INVALIDDATA;
if (extend >= channel_map_size)
*got_frame_ptr = 1;
if (!s->superframe_size)
- return FFMIN(full_buf_size, s->frame_size);
+ return FFMIN(full_buf_size, s->frame_size + skip);
- return FFMIN(full_buf_size, s->superframe_size);
+ return FFMIN(full_buf_size, s->superframe_size + skip);
}
/**