diff options
Diffstat (limited to 'libavutil/fifo.c')
-rw-r--r-- | libavutil/fifo.c | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/libavutil/fifo.c b/libavutil/fifo.c index dffaf54533..ca25bc5239 100644 --- a/libavutil/fifo.c +++ b/libavutil/fifo.c @@ -3,22 +3,24 @@ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard * Copyright (c) 2006 Roman Shaposhnik * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "avassert.h" #include "common.h" #include "fifo.h" @@ -38,7 +40,7 @@ AVFifoBuffer *av_fifo_alloc(unsigned int size) void av_fifo_free(AVFifoBuffer *f) { if (f) { - av_free(f->buffer); + av_freep(&f->buffer); av_free(f); } } @@ -68,7 +70,7 @@ int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size) AVFifoBuffer *f2 = av_fifo_alloc(new_size); if (!f2) - return -1; + return AVERROR(ENOMEM); av_fifo_generic_read(f, f2->buffer, len, NULL); f2->wptr += len; f2->wndx += len; @@ -79,28 +81,46 @@ int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size) return 0; } +int av_fifo_grow(AVFifoBuffer *f, unsigned int size) +{ + unsigned int old_size = f->end - f->buffer; + if(size + (unsigned)av_fifo_size(f) < size) + return AVERROR(EINVAL); + + size += av_fifo_size(f); + + if (old_size < size) + return av_fifo_realloc2(f, FFMAX(size, 2*size)); + return 0; +} + /* src must NOT be const as it can be a context for func that may need * updating (like a pointer or byte counter) */ int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void *, void *, int)) { int total = size; + uint32_t wndx= f->wndx; + uint8_t *wptr= f->wptr; + do { - int len = FFMIN(f->end - f->wptr, size); + int len = FFMIN(f->end - wptr, size); if (func) { - if (func(src, f->wptr, len) <= 0) + if (func(src, wptr, len) <= 0) break; } else { - memcpy(f->wptr, src, len); + memcpy(wptr, src, len); src = (uint8_t *)src + len; } // Write memory barrier needed for SMP here in theory - f->wptr += len; - if (f->wptr >= f->end) - f->wptr = f->buffer; - f->wndx += len; + wptr += len; + if (wptr >= f->end) + wptr = f->buffer; + wndx += len; size -= len; } while (size > 0); + f->wndx= wndx; + f->wptr= wptr; return total - size; } @@ -126,6 +146,7 @@ int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, /** Discard data from the FIFO. */ void av_fifo_drain(AVFifoBuffer *f, int size) { + av_assert2(av_fifo_size(f) >= size); f->rptr += size; if (f->rptr >= f->end) f->rptr -= f->end - f->buffer; |