aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>2011-03-05 13:49:13 +0100
committerReimar Döffinger <Reimar.Doeffinger@gmx.de>2011-03-19 12:07:14 +0100
commitc9f6eab184cac379c7a44d5899979165798d45d4 (patch)
treeecbf06e2304208b34555bee05266967bf48800ec /libavcodec
parent19d82cb14cc5967b8e09b242da1c2aa2d32be028 (diff)
downloadffmpeg-c9f6eab184cac379c7a44d5899979165798d45d4.tar.gz
Detect byte-swapped AC-3 (aka DNET) and support decoding it directly.
This allows the AC-3 decoder to be used directly with RealMedia decoders that unlike the libavformat one do not byte-swap automatically. Since the new code is only used in case we would fail directly otherwise there should be no risk for regressions. The "buf" pointer needs to be overwritten since otherwise the CRC check fails.
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/ac3dec.c26
1 files changed, 15 insertions, 11 deletions
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;