flac_parser: loop append buffer when the default size is not enough to get

the desired number of frames.
Patch by Michael Chinen [mchinen at gmail]

Originally committed as revision 26163 to svn://svn.ffmpeg.org/ffmpeg/trunk
oldabi
Michael Chinen 14 years ago committed by Justin Ruggles
parent 536e9b2f58
commit 4b5d4720c1
  1. 39
      libavcodec/flac_parser.c

@ -478,7 +478,8 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
FLACParseContext *fpc = s->priv_data; FLACParseContext *fpc = s->priv_data;
FLACHeaderMarker *curr; FLACHeaderMarker *curr;
int nb_headers; int nb_headers;
int read_size = 0; const uint8_t *read_end = buf;
const uint8_t *read_start = buf;
if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
FLACFrameInfo fi; FLACFrameInfo fi;
@ -540,31 +541,36 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
} }
/* Find and score new headers. */ /* Find and score new headers. */
if (buf_size || !fpc->end_padded) { while ((buf && read_end < buf + buf_size &&
fpc->nb_headers_buffered < FLAC_MIN_HEADERS)
|| (!buf && !fpc->end_padded)) {
int start_offset; int start_offset;
/* Pad the end once if EOF, to check the final region for headers. */ /* Pad the end once if EOF, to check the final region for headers. */
if (!buf_size) { if (!buf) {
fpc->end_padded = 1; fpc->end_padded = 1;
buf_size = read_size = MAX_FRAME_HEADER_SIZE; buf_size = MAX_FRAME_HEADER_SIZE;
read_end = read_start + MAX_FRAME_HEADER_SIZE;
} else { } else {
/* The maximum read size is the upper-bound of what the parser /* The maximum read size is the upper-bound of what the parser
needs to have the required number of frames buffered */ needs to have the required number of frames buffered */
int nb_desired = FLAC_MIN_HEADERS - fpc->nb_headers_buffered + 1; int nb_desired = FLAC_MIN_HEADERS - fpc->nb_headers_buffered + 1;
read_size = FFMIN(buf_size, nb_desired * FLAC_AVG_FRAME_SIZE); read_end = read_end + FFMIN(buf + buf_size - read_end,
nb_desired * FLAC_AVG_FRAME_SIZE);
} }
/* Fill the buffer. */ /* Fill the buffer. */
if (av_fifo_realloc2(fpc->fifo_buf, if (av_fifo_realloc2(fpc->fifo_buf,
read_size + av_fifo_size(fpc->fifo_buf)) < 0) { (read_end - read_start) + av_fifo_size(fpc->fifo_buf)) < 0) {
av_log(avctx, AV_LOG_ERROR, av_log(avctx, AV_LOG_ERROR,
"couldn't reallocate buffer of size %d\n", "couldn't reallocate buffer of size %d\n",
read_size + av_fifo_size(fpc->fifo_buf)); (read_end - read_start) + av_fifo_size(fpc->fifo_buf));
goto handle_error; goto handle_error;
} }
if (buf) { if (buf) {
av_fifo_generic_write(fpc->fifo_buf, (void*) buf, read_size, NULL); av_fifo_generic_write(fpc->fifo_buf, (void*) read_start,
read_end - read_start, NULL);
} else { } else {
int8_t pad[MAX_FRAME_HEADER_SIZE]; int8_t pad[MAX_FRAME_HEADER_SIZE];
memset(pad, 0, sizeof(pad)); memset(pad, 0, sizeof(pad));
@ -573,7 +579,7 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
/* Tag headers and update sequences. */ /* Tag headers and update sequences. */
start_offset = av_fifo_size(fpc->fifo_buf) - start_offset = av_fifo_size(fpc->fifo_buf) -
(read_size + (MAX_FRAME_HEADER_SIZE - 1)); ((read_end - read_start) + (MAX_FRAME_HEADER_SIZE - 1));
start_offset = FFMAX(0, start_offset); start_offset = FFMAX(0, start_offset);
nb_headers = find_new_headers(fpc, start_offset); nb_headers = find_new_headers(fpc, start_offset);
@ -585,8 +591,14 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
fpc->nb_headers_buffered = nb_headers; fpc->nb_headers_buffered = nb_headers;
/* Wait till FLAC_MIN_HEADERS to output a valid frame. */ /* Wait till FLAC_MIN_HEADERS to output a valid frame. */
if (!fpc->end_padded && fpc->nb_headers_buffered < FLAC_MIN_HEADERS) if (!fpc->end_padded && fpc->nb_headers_buffered < FLAC_MIN_HEADERS) {
if (buf && read_end < buf + buf_size) {
read_start = read_end;
continue;
} else {
goto handle_error; goto handle_error;
}
}
/* If headers found, update the scores since we have longer chains. */ /* If headers found, update the scores since we have longer chains. */
if (fpc->end_padded || fpc->nb_headers_found) if (fpc->end_padded || fpc->nb_headers_found)
@ -601,7 +613,8 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
fpc->fifo_buf->wptr += fpc->fifo_buf->end - fpc->fifo_buf->wptr += fpc->fifo_buf->end -
fpc->fifo_buf->buffer; fpc->fifo_buf->buffer;
} }
buf_size = read_size = 0; buf_size = 0;
read_start = read_end = NULL;
} }
} }
@ -623,7 +636,7 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
*poutbuf = flac_fifo_read_wrap(fpc, 0, *poutbuf_size, *poutbuf = flac_fifo_read_wrap(fpc, 0, *poutbuf_size,
&fpc->wrap_buf, &fpc->wrap_buf,
&fpc->wrap_buf_allocated_size); &fpc->wrap_buf_allocated_size);
return buf_size ? read_size : (fpc->best_header->offset - return buf_size ? (read_end - buf) : (fpc->best_header->offset -
av_fifo_size(fpc->fifo_buf)); av_fifo_size(fpc->fifo_buf));
} }
if (!buf_size) if (!buf_size)
@ -633,7 +646,7 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
handle_error: handle_error:
*poutbuf = NULL; *poutbuf = NULL;
*poutbuf_size = 0; *poutbuf_size = 0;
return read_size; return read_end - buf;
} }
static int flac_parse_init(AVCodecParserContext *c) static int flac_parse_init(AVCodecParserContext *c)

Loading…
Cancel
Save