00001 /* 00002 * a very simple circular buffer FIFO implementation 00003 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard 00004 * Copyright (c) 2006 Roman Shaposhnik 00005 * 00006 * This file is part of FFmpeg. 00007 * 00008 * FFmpeg is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * FFmpeg is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with FFmpeg; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 #include "common.h" 00023 #include "fifo.h" 00024 00025 int av_fifo_init(AVFifoBuffer *f, unsigned int size) 00026 { 00027 size= FFMAX(size, size+1); 00028 f->wptr = f->rptr = 00029 f->buffer = av_malloc(size); 00030 f->end = f->buffer + size; 00031 if (!f->buffer) 00032 return -1; 00033 return 0; 00034 } 00035 00036 void av_fifo_free(AVFifoBuffer *f) 00037 { 00038 av_free(f->buffer); 00039 } 00040 00041 int av_fifo_size(AVFifoBuffer *f) 00042 { 00043 int size = f->wptr - f->rptr; 00044 if (size < 0) 00045 size += f->end - f->buffer; 00046 return size; 00047 } 00048 00049 int av_fifo_read(AVFifoBuffer *f, uint8_t *buf, int buf_size) 00050 { 00051 return av_fifo_generic_read(f, buf_size, NULL, buf); 00052 } 00053 00054 #if LIBAVUTIL_VERSION_MAJOR < 50 00055 void av_fifo_realloc(AVFifoBuffer *f, unsigned int new_size) { 00056 av_fifo_realloc2(f, new_size); 00057 } 00058 #endif 00059 00060 int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size) { 00061 unsigned int old_size= f->end - f->buffer; 00062 00063 if(old_size <= new_size){ 00064 int len= av_fifo_size(f); 00065 AVFifoBuffer f2; 00066 00067 if (av_fifo_init(&f2, new_size) < 0) 00068 return -1; 00069 av_fifo_read(f, f2.buffer, len); 00070 f2.wptr += len; 00071 av_free(f->buffer); 00072 *f= f2; 00073 } 00074 return 0; 00075 } 00076 00077 #if LIBAVUTIL_VERSION_MAJOR < 50 00078 void av_fifo_write(AVFifoBuffer *f, const uint8_t *buf, int size) 00079 { 00080 av_fifo_generic_write(f, (void *)buf, size, NULL); 00081 } 00082 #endif 00083 00084 int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int)) 00085 { 00086 int total = size; 00087 do { 00088 int len = FFMIN(f->end - f->wptr, size); 00089 if(func) { 00090 if(func(src, f->wptr, len) <= 0) 00091 break; 00092 } else { 00093 memcpy(f->wptr, src, len); 00094 src = (uint8_t*)src + len; 00095 } 00096 f->wptr += len; 00097 if (f->wptr >= f->end) 00098 f->wptr = f->buffer; 00099 size -= len; 00100 } while (size > 0); 00101 return total - size; 00102 } 00103 00104 00105 int av_fifo_generic_read(AVFifoBuffer *f, int buf_size, void (*func)(void*, void*, int), void* dest) 00106 { 00107 do { 00108 int len = FFMIN(f->end - f->rptr, buf_size); 00109 if(func) func(dest, f->rptr, len); 00110 else{ 00111 memcpy(dest, f->rptr, len); 00112 dest = (uint8_t*)dest + len; 00113 } 00114 av_fifo_drain(f, len); 00115 buf_size -= len; 00116 } while (buf_size > 0); 00117 return 0; 00118 } 00119 00121 void av_fifo_drain(AVFifoBuffer *f, int size) 00122 { 00123 f->rptr += size; 00124 if (f->rptr >= f->end) 00125 f->rptr -= f->end - f->buffer; 00126 }