From d0269db8e3369fddcfe5ce9daface2b95dde48da Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 18 Dec 2011 20:12:16 +0100 Subject: [PATCH] adx_parser: rewrite. The previous code ended in multiple different infinite loops. See stl_ten_1_big.sfd as example with and without zzuf Signed-off-by: Michael Niedermayer (cherry picked from commit 7859740c6a2f9bc3dd247dc63b8e7cbd6181a5dd) Signed-off-by: Michael Niedermayer --- libavcodec/adx_parser.c | 61 ++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 38 deletions(-) diff --git a/libavcodec/adx_parser.c b/libavcodec/adx_parser.c index f5d7989ecf..bbd865454e 100644 --- a/libavcodec/adx_parser.c +++ b/libavcodec/adx_parser.c @@ -22,7 +22,7 @@ * @file * ADX audio parser * - * Reads header to extradata and splits packets into individual blocks. + * Splits packets into individual blocks. */ #include "libavutil/intreadwrite.h" @@ -33,11 +33,9 @@ typedef struct ADXParseContext { ParseContext pc; int header_size; int block_size; - int buf_pos; + int remaining; } ADXParseContext; -#define MIN_HEADER_SIZE 24 - static int adx_parse(AVCodecParserContext *s1, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, @@ -46,45 +44,32 @@ static int adx_parse(AVCodecParserContext *s1, ADXParseContext *s = s1->priv_data; ParseContext *pc = &s->pc; int next = END_NOT_FOUND; + int i; + uint64_t state= pc->state64; - if (!avctx->extradata_size) { - int ret; - - ff_combine_frame(pc, END_NOT_FOUND, &buf, &buf_size); - - if (!s->header_size && pc->index >= MIN_HEADER_SIZE) { - if (ret = avpriv_adx_decode_header(avctx, pc->buffer, pc->index, - &s->header_size, NULL)) - return AVERROR_INVALIDDATA; + if(!s->header_size){ + for(i=0; i>32)&0xFFFF)>=4){ + s->header_size= ((state>>32)&0xFFFF) + 4; + s->block_size = BLOCK_SIZE * (state&0xFF); + s->remaining = i - 7 + s->header_size + s->block_size; + break; + } } - if (s->header_size && s->header_size <= pc->index) { - avctx->extradata = av_mallocz(s->header_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!avctx->extradata) - return AVERROR(ENOMEM); - avctx->extradata_size = s->header_size; - memcpy(avctx->extradata, pc->buffer, s->header_size); - memmove(pc->buffer, pc->buffer + s->header_size, s->header_size); - pc->index -= s->header_size; - } - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; + pc->state64= state; } - s->block_size = BLOCK_SIZE * avctx->channels; - if (pc->index - s->buf_pos >= s->block_size) { - *poutbuf = &pc->buffer[s->buf_pos]; - *poutbuf_size = s->block_size; - s->buf_pos += s->block_size; - return 0; + if (s->header_size) { + if (!s->remaining) { + s->remaining = s->block_size; + } + if (s->remaining<=buf_size) { + next= s->remaining; + s->remaining = 0; + } else + s->remaining -= buf_size; } - if (pc->index && s->buf_pos) { - memmove(pc->buffer, &pc->buffer[s->buf_pos], pc->index - s->buf_pos); - pc->index -= s->buf_pos; - s->buf_pos = 0; - } - if (buf_size + pc->index >= s->block_size) - next = s->block_size - pc->index; if (ff_combine_frame(pc, next, &buf, &buf_size) < 0 || !buf_size) { *poutbuf = NULL;