ffmpeg / libavutil / fifo.c @ 4b2be143
History | View | Annotate | Download (3.31 KB)
1 | f5a478f6 | Roman Shaposhnik | /*
|
---|---|---|---|
2 | 89c9ff50 | Diego Biurrun | * a very simple circular buffer FIFO implementation
|
3 | f5a478f6 | Roman Shaposhnik | * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
|
4 | * Copyright (c) 2006 Roman Shaposhnik
|
||
5 | *
|
||
6 | b78e7197 | Diego Biurrun | * This file is part of FFmpeg.
|
7 | *
|
||
8 | * FFmpeg is free software; you can redistribute it and/or
|
||
9 | f5a478f6 | Roman Shaposhnik | * modify it under the terms of the GNU Lesser General Public
|
10 | * License as published by the Free Software Foundation; either
|
||
11 | b78e7197 | Diego Biurrun | * version 2.1 of the License, or (at your option) any later version.
|
12 | f5a478f6 | Roman Shaposhnik | *
|
13 | b78e7197 | Diego Biurrun | * FFmpeg is distributed in the hope that it will be useful,
|
14 | f5a478f6 | Roman Shaposhnik | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
16 | * Lesser General Public License for more details.
|
||
17 | *
|
||
18 | * You should have received a copy of the GNU Lesser General Public
|
||
19 | b78e7197 | Diego Biurrun | * License along with FFmpeg; if not, write to the Free Software
|
20 | f5a478f6 | Roman Shaposhnik | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
21 | */
|
||
22 | #include "common.h" |
||
23 | #include "fifo.h" |
||
24 | |||
25 | 41dd680d | Michael Niedermayer | AVFifoBuffer *av_fifo_alloc(unsigned int size) |
26 | f5a478f6 | Roman Shaposhnik | { |
27 | 41dd680d | Michael Niedermayer | AVFifoBuffer *f= av_mallocz(sizeof(AVFifoBuffer));
|
28 | if(!f)
|
||
29 | return NULL; |
||
30 | f5a478f6 | Roman Shaposhnik | f->buffer = av_malloc(size); |
31 | 4497712f | Michael Niedermayer | f->end = f->buffer + size; |
32 | 32b936d0 | Reimar Döffinger | av_fifo_reset(f); |
33 | f5a478f6 | Roman Shaposhnik | if (!f->buffer)
|
34 | 41dd680d | Michael Niedermayer | av_freep(&f); |
35 | return f;
|
||
36 | f5a478f6 | Roman Shaposhnik | } |
37 | |||
38 | void av_fifo_free(AVFifoBuffer *f)
|
||
39 | { |
||
40 | 41dd680d | Michael Niedermayer | if(f){
|
41 | c900635f | Michael Niedermayer | av_free(f->buffer); |
42 | av_free(f); |
||
43 | 41dd680d | Michael Niedermayer | } |
44 | f5a478f6 | Roman Shaposhnik | } |
45 | |||
46 | 32b936d0 | Reimar Döffinger | void av_fifo_reset(AVFifoBuffer *f)
|
47 | { |
||
48 | f->wptr = f->rptr = f->buffer; |
||
49 | f->wndx = f->rndx = 0;
|
||
50 | } |
||
51 | |||
52 | f5a478f6 | Roman Shaposhnik | int av_fifo_size(AVFifoBuffer *f)
|
53 | { |
||
54 | 0a71e78c | Michael Niedermayer | return (uint32_t)(f->wndx - f->rndx);
|
55 | f5a478f6 | Roman Shaposhnik | } |
56 | |||
57 | 7b09db35 | Olivier Guilyardi | int av_fifo_space(AVFifoBuffer *f)
|
58 | { |
||
59 | return f->end - f->buffer - av_fifo_size(f);
|
||
60 | } |
||
61 | |||
62 | 8257b835 | Stefano Sabatini | int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size) { |
63 | f5a478f6 | Roman Shaposhnik | unsigned int old_size= f->end - f->buffer; |
64 | |||
65 | 0a71e78c | Michael Niedermayer | if(old_size < new_size){
|
66 | 96e39edc | Michael Niedermayer | int len= av_fifo_size(f);
|
67 | 41dd680d | Michael Niedermayer | AVFifoBuffer *f2= av_fifo_alloc(new_size); |
68 | f5a478f6 | Roman Shaposhnik | |
69 | 41dd680d | Michael Niedermayer | if (!f2)
|
70 | 8257b835 | Stefano Sabatini | return -1; |
71 | 3898eed8 | Reimar Döffinger | av_fifo_generic_read(f, f2->buffer, len, NULL);
|
72 | 41dd680d | Michael Niedermayer | f2->wptr += len; |
73 | f2->wndx += len; |
||
74 | 96e39edc | Michael Niedermayer | av_free(f->buffer); |
75 | 41dd680d | Michael Niedermayer | *f= *f2; |
76 | av_free(f2); |
||
77 | f5a478f6 | Roman Shaposhnik | } |
78 | 8257b835 | Stefano Sabatini | return 0; |
79 | f5a478f6 | Roman Shaposhnik | } |
80 | |||
81 | 95c76e11 | Benoit Fouet | int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int)) |
82 | 49cec199 | Björn Axelsson | { |
83 | int total = size;
|
||
84 | 50b44685 | Michael Niedermayer | do {
|
85 | 870a12d1 | Michael Niedermayer | int len = FFMIN(f->end - f->wptr, size);
|
86 | 49cec199 | Björn Axelsson | if(func) {
|
87 | 95c76e11 | Benoit Fouet | if(func(src, f->wptr, len) <= 0) |
88 | 49cec199 | Björn Axelsson | break;
|
89 | } else {
|
||
90 | 95c76e11 | Benoit Fouet | memcpy(f->wptr, src, len); |
91 | src = (uint8_t*)src + len; |
||
92 | 49cec199 | Björn Axelsson | } |
93 | a9364759 | Michael Niedermayer | // Write memory barrier needed for SMP here in theory
|
94 | f5a478f6 | Roman Shaposhnik | f->wptr += len; |
95 | if (f->wptr >= f->end)
|
||
96 | f->wptr = f->buffer; |
||
97 | 0a71e78c | Michael Niedermayer | f->wndx += len; |
98 | f5a478f6 | Roman Shaposhnik | size -= len; |
99 | 50b44685 | Michael Niedermayer | } while (size > 0); |
100 | 49cec199 | Björn Axelsson | return total - size;
|
101 | f5a478f6 | Roman Shaposhnik | } |
102 | |||
103 | |||
104 | 3898eed8 | Reimar Döffinger | int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int)) |
105 | f5a478f6 | Roman Shaposhnik | { |
106 | a9364759 | Michael Niedermayer | // Read memory barrier needed for SMP here in theory
|
107 | 50b44685 | Michael Niedermayer | do {
|
108 | 870a12d1 | Michael Niedermayer | int len = FFMIN(f->end - f->rptr, buf_size);
|
109 | 765d4f3b | Michael Niedermayer | if(func) func(dest, f->rptr, len);
|
110 | else{
|
||
111 | memcpy(dest, f->rptr, len); |
||
112 | dest = (uint8_t*)dest + len; |
||
113 | } |
||
114 | a9364759 | Michael Niedermayer | // memory barrier needed for SMP here in theory
|
115 | 3da97cfd | Michael Niedermayer | av_fifo_drain(f, len); |
116 | f5a478f6 | Roman Shaposhnik | buf_size -= len; |
117 | 50b44685 | Michael Niedermayer | } while (buf_size > 0); |
118 | f5a478f6 | Roman Shaposhnik | return 0; |
119 | } |
||
120 | |||
121 | 89c9ff50 | Diego Biurrun | /** Discard data from the FIFO. */
|
122 | f5a478f6 | Roman Shaposhnik | void av_fifo_drain(AVFifoBuffer *f, int size) |
123 | { |
||
124 | f->rptr += size; |
||
125 | if (f->rptr >= f->end)
|
||
126 | f->rptr -= f->end - f->buffer; |
||
127 | 0a71e78c | Michael Niedermayer | f->rndx += size; |
128 | f5a478f6 | Roman Shaposhnik | } |