lavu/fifo: do not copy the whole fifo when reallocating
av_realloc() the buffer and only move the part of the ring buffer that needs it. Also avoids allocating a temporary fifo.
This commit is contained in:
parent
5010c481d1
commit
549ccea54e
|
@ -27,7 +27,7 @@
|
||||||
AVFifoBuffer *av_fifo_alloc_array(size_t nmemb, size_t size)
|
AVFifoBuffer *av_fifo_alloc_array(size_t nmemb, size_t size)
|
||||||
{
|
{
|
||||||
AVFifoBuffer *f;
|
AVFifoBuffer *f;
|
||||||
void *buffer = av_malloc_array(nmemb, size);
|
void *buffer = av_realloc_array(NULL, nmemb, size);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
return NULL;
|
return NULL;
|
||||||
f = av_mallocz(sizeof(AVFifoBuffer));
|
f = av_mallocz(sizeof(AVFifoBuffer));
|
||||||
|
@ -83,17 +83,31 @@ int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size)
|
||||||
unsigned int old_size = f->end - f->buffer;
|
unsigned int old_size = f->end - f->buffer;
|
||||||
|
|
||||||
if (old_size < new_size) {
|
if (old_size < new_size) {
|
||||||
int len = av_fifo_size(f);
|
size_t offset_r = f->rptr - f->buffer;
|
||||||
AVFifoBuffer *f2 = av_fifo_alloc(new_size);
|
size_t offset_w = f->wptr - f->buffer;
|
||||||
|
uint8_t *tmp;
|
||||||
|
|
||||||
if (!f2)
|
tmp = av_realloc(f->buffer, new_size);
|
||||||
|
if (!tmp)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
av_fifo_generic_read(f, f2->buffer, len, NULL);
|
|
||||||
f2->wptr += len;
|
// move the data from the beginning of the ring buffer
|
||||||
f2->wndx += len;
|
// to the newly allocated space
|
||||||
av_free(f->buffer);
|
// the second condition distinguishes full vs empty fifo
|
||||||
*f = *f2;
|
if (offset_w <= offset_r && av_fifo_size(f)) {
|
||||||
av_free(f2);
|
const size_t copy = FFMIN(new_size - old_size, offset_w);
|
||||||
|
memcpy(tmp + old_size, tmp, copy);
|
||||||
|
if (copy < offset_w) {
|
||||||
|
memmove(tmp, tmp + copy , offset_w - copy);
|
||||||
|
offset_w -= copy;
|
||||||
|
} else
|
||||||
|
offset_w = old_size + copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
f->buffer = tmp;
|
||||||
|
f->end = f->buffer + new_size;
|
||||||
|
f->rptr = f->buffer + offset_r;
|
||||||
|
f->wptr = f->buffer + offset_w;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue