diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 5ebee1908d..fbcfdb0ce9 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -207,13 +207,6 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) } 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; } @@ -1312,16 +1305,27 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, int blk, ch, err; const uint8_t *channel_map; const float *output[AC3_MAX_CHANNELS]; + // if it seems to be byte-swapped AC-3 (aka DNET) + int is_swapped = buf_size >= 2 && AV_RB16(buf) == 0x770B; /* initialize the GetBitContext with the start of valid AC-3 Frame */ - if (s->input_buffer) { + if (is_swapped || avctx->error_recognition >= FF_ER_CAREFUL) { + /* allocate context input buffer */ + if (!s->input_buffer) + s->input_buffer = av_mallocz(AC3_FRAME_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); + if (!s->input_buffer) + return AVERROR(ENOMEM); + /* 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 (is_swapped) { + int cnt = FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE) >> 1; + s->dsp.bswap16_buf(s->input_buffer, 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; } + init_get_bits(&s->gbc, buf, buf_size * 8); /* parse the syncinfo */ *data_size = 0;