diff options
author | Zhang Rui <bbcallen@gmail.com> | 2015-10-14 14:20:07 +0800 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2015-10-14 20:23:58 +0200 |
commit | 87ff61b9abde99d8cdc2a4332b41f69a80eb3d56 (patch) | |
tree | d92e410c5d20a65bbf9b4b454e243cdc7d016948 /libavutil/fifo.c | |
parent | 55d3e97970888baa173061704a085144c5a014b4 (diff) | |
download | ffmpeg-87ff61b9abde99d8cdc2a4332b41f69a80eb3d56.tar.gz |
avutil/fifo: add function av_fifo_generic_peek_at()
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavutil/fifo.c')
-rw-r--r-- | libavutil/fifo.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/libavutil/fifo.c b/libavutil/fifo.c index 1a227087be..7bd48a2271 100644 --- a/libavutil/fifo.c +++ b/libavutil/fifo.c @@ -148,6 +148,44 @@ int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, return total - size; } +int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void (*func)(void*, void*, int)) +{ + uint8_t *rptr = f->rptr; + + av_assert2(offset >= 0); + + /* + * *ndx are indexes modulo 2^32, they are intended to overflow, + * to handle *ndx greater than 4gb. + */ + av_assert2(buf_size + (unsigned)offset <= f->wndx - f->rndx); + + if (offset >= f->end - rptr) + rptr += offset - (f->end - f->buffer); + else + rptr += offset; + + while (buf_size > 0) { + int len; + + if (rptr >= f->end) + rptr -= f->end - f->buffer; + + len = FFMIN(f->end - rptr, buf_size); + if (func) + func(dest, rptr, len); + else { + memcpy(dest, rptr, len); + dest = (uint8_t *)dest + len; + } + + buf_size -= len; + rptr += len; + } + + return 0; +} + int av_fifo_generic_peek(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void *, void *, int)) { @@ -221,6 +259,14 @@ int main(void) } printf("\n"); + /* peek_at at FIFO */ + n = av_fifo_size(fifo) / sizeof(int); + for (i = 0; i < n; i++) { + av_fifo_generic_peek_at(fifo, &j, i * sizeof(int), sizeof(j), NULL); + printf("%d: %d\n", i, j); + } + printf("\n"); + /* read data */ for (i = 0; av_fifo_size(fifo) >= sizeof(int); i++) { av_fifo_generic_read(fifo, &j, sizeof(int), NULL); @@ -228,6 +274,21 @@ int main(void) } printf("\n"); + /* test *ndx overflow */ + av_fifo_reset(fifo); + fifo->rndx = fifo->wndx = ~(uint32_t)0 - 5; + + /* fill data */ + for (i = 0; av_fifo_space(fifo) >= sizeof(int); i++) + av_fifo_generic_write(fifo, &i, sizeof(int), NULL); + + /* peek_at at FIFO */ + n = av_fifo_size(fifo) / sizeof(int); + for (i = 0; i < n; i++) { + av_fifo_generic_peek_at(fifo, &j, i * sizeof(int), sizeof(j), NULL); + printf("%d: %d\n", i, j); + } + av_fifo_free(fifo); return 0; |